变量声明与初始化
Go语言是静态类型语言,变量有明确=类型,编译器也会检查变量类型的正确性。变量声明标准格式如下:
�var name type // 关键字 变量名 变量类型
不同于C语言,Go变量类型在后面, 避免混淆,如var a,b int *
把a,b都声明称指针类型的变量。
变量初始化标准格式:
var name type = value
备注:当一个变量被声明后,会自动赋予零值:int 为 0,float 为 0.0,bool 为 false,string 为空字符串,指针为 nil 等。所有的内存在 Go 中都是经过初始化的。
其他声明方式如下:
1. 批量声明:使用关键字 var 和括号,可以将一组变量定义放在一起。
var (
a int
b string
c float
)
2. 简短格式
num := 10 //num = 10
I,j := 1,2 //I=1;j=2
简短格式有如下限制:1)定义变量,同时初始化;2)无需定义数据类型;3)只能在函数内用。简短格式广泛用于局部变量的声明和定义,var形式常用于需要显示定义变量类型的地方。
注意:在多个短变量声明和赋值中,至少有一个新声明的变量出现在左值中,即便其他变量名可能是重复声明的。
conn, err := net.Dial(“tcp”, “127.0.0.1:8080”)
conn2, err := net.Dial(“tcp”, “127.0.0.1:8080”)
基本数据类型
* bool
* string
* int、int8、int16、int32、int64
* uint、uint8、uint16、uint32、uint64、uintptr
* byte // uint8 的别名
* rune // int32 的别名 代表一个 Unicode 码
* float32、float64
* complex64、complex128
多重赋值
GO语言神奇的变量交换动作,多重赋值特性
var a int = 100
var b int = 200
a, b = b,a
匿名变量
没有名字的变量,表示没有用到可以忽略的变量,用_
空白标识符表示。它可以被声明和赋值,但不会用到。匿名变量不占用内存空间,不会分配内存。匿名变量与匿名变量之间也不会因为多次声明而无法使用。使用方法如教程中的示例代码:
func GetData() (int, int) {
return 100, 200
}
func main(){
a, _ := GetData()
_, b := GetData()
fmt.Println(a, b)
}
变量作用域
Go语言会在编译时检查每个变量是否使用过,一旦出现未使用的变量,就会报编译错误。根据变量定义的位置,分为局部变量、全局变量、函数形参三种。
局部变量在函数内声明,作用域只在函数内,函数的参数(即形参)和返回值都是均属于局部变量,局部变量在函数被调用时创建,函数调用结束被销毁;
在函数体外声明的变量称之为全局变量,全局变量只需要在一个源文件中定义,就可以在所有源文件中使用,当然,不包含这个全局变量的源文件需要使用“import”关键字引入全局变量所在的源文件之后才能使用这个全局变量。全局变量声明必须以 var 关键字开头,如果想要在外部包中使用全局变量的首字母必须大写。Go语言程序中全局变量与局部变量名称可以相同,但是函数体内的局部变量会被优先考虑。
整型与浮点型
整型有有符号和无符号整型,包括int8、int16、int32 和 int64四种有符号整型和对应的uint8、uint16、uint32 和 uint64 四种无符号整数类型,分别对应8、16、32、64位大小的整数。
此外最常用的是int 和 uint,表示对应CPU系统的字长,即会根据系统表示范围在32bit和64bit间变化
浮点型有float32和float64两种精度,一个 float32 类型的浮点数可以提供大约 6 个十进制数的精度,而 float64 则可以提供约 15 个十进制数的精度。
浮点数在声明的时候可以只写整数部分或者小数部分,方式如下:
var e float32 = .717 //0.717
cosnt f = 1. //1
const planck = 6.62606957e-3 //普朗克常数
布尔类型
布尔类型值只有:true或false,常用与条件语句,与==、> 、<
等操作使用,也可以和&& 和 ||操作符结合(&&的优先级比||高)。
与C语言不同的一点: GO语言中的布尔类型不会隐式转换称0或1,反之亦然,必须显示转换:
//布尔转0、1
func btoi(b bool) int {
if b {
return 1
}
return 0
}
// 0/1转布尔
func itob(i int) bool { return i != 0 }
字符串
Go语言有字符串类型:字符串是 UTF-8 字符的一个序列。字符串是一种值类型,且值不可变,使用双引号””来定义字符串。
package main
import ”fmt“
func main(){
var str = “hahahahha”
fmt.Println(str)
}
字符串拼接符“+” :s := s1 + s2,如
str := “hellow ” + “Go”
str += “ world!”
字符类型
字符串的每个元素,类似C语言中的char类型,Go语言中有两种:
* byte型,uint8类型,代表ASCII码的一个字符(C语言的char)
* rune类型,代表一个UTF-8字符,等价于int32类型,处理中文等字符使用。
var ch byte = ‘A’
var ch2 byte = 65
var ch3 byte = ‘\x41’
Var ch4 byte = ‘\377’
var ch int = '\u0041'
var ch2 int = '\u03B2'
var ch3 int = '\U00101234'
类型转换
Go语言不存在隐式类型转换,所有转换都要显示声明:
a := 6.0
b := int(a)
类型转换只能在定义正确的情况下转换成功,例如从一个取值范围较小的类型转换到一个取值范围较大的类型(将 int16 转换为 int32)。当从一个取值范围较大的类型转换到取值范围较小的类型时(将 int32 转换为 int16 或将 float32 转换为 int),会发生精度丢失(截断)的情况。
只有相同底层类型的变量之间可以进行相互转换(如将 int16 类型转换成 int32 类型),不同底层类型的变量相互转换时会引发编译错误(如将 bool 类型转换为 int 类型).
指针类型
指针(pointer)在Go语言中可以被拆分为两个核心概念:
* 类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
* 切片,由指向起始元素的原始指针、元素数量和容量组成。
要明白指针,需要知道几个概念:指针地址、指针类型和指针取值。
指针类型:一个指针变量可以指向任何一个值得内存地址,指针变量指向一个4或8字节的地址,如果指针被定义没有复制,默认值是nil。
指针地址:每个变量在运行时都有一个地址,代表内存中的位置。GO语言也是通过&
获取变量的内存地址
ptr := &v
Tips: 变量、指针和地址三者的关系是,每个变量都拥有地址,指针的值就是地址。
指针取值:*
,取地址操作符&和取值操作符是一对互补操作符,&取出地址,根据地址取出地址指向的值。
变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
* 对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
* 指针变量的值是指针地址。
* 对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。
创建指针的另一种方法:new()函数,new() 函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向默认值。
str := new(string)
*str = “hellow go china”
fmt.Println(*str)
常量
常量用关键字const
定义,用于存储不会改变的的数据,常量是在编译时被创建的,常量定义格式如下const name type = value
,比如:
const pi = 3.1415
Go语言定义时可省略类型说明符,编译器会根据值来推断其类型。
* 显式定义:const b string = “aaa”
* 隐式定义: const b = “aaa”
批量声明常量时,除了第一个外其他的都可以省略,如果省略初始表达式则表示使用前面的初始化表达式,对应类型也一样,如:
const (
a = 1
b
c = 2
d
)
fmt.Println(a,b,c,d) // 1 1 2 2
常量生成器 iota:用于生产一组相似规则初始化的常量,但不用每行都写一遍初始化表达式,在const声明时,第一行声明的常量 iota会被置0,然后么一行加1,例如:
type Weekday int
const (
SUNDAY Weekday = iota //0
MONDAY // 1
TUESDAT // 2
WEDNESDAY // 3
THURSDAY //4
FRIDAY // 5
SATURDAY // 6
)
无类型常量:常量并没有一个明确的基础类型,编译器为这些没有明确的基础类型的数字常量提供比基础类型更高精度的算术运算,可以认为至少有 256bit 的运算精度。这里有六种未明确类型的常量类型,分别是无类型的布尔型、无类型的整数、无类型的字符、无类型的浮点数、无类型的复数、无类型的字符串。通过延迟明确常量的具体类型,不仅可以提供更高的运算精度,而且可以直接用于更多的表达式而不需要显式的类型转换。例如:
var x float32 = math.Pi
var y float64 = math.Pi
var z complex128 = math.Pi
类型别名
类型别名定义(GO 1.9之后版本):type TypeAlias = Type
。TypeAlias只是Type的别名,本质上是同一类型。下面例子a的类型是NewInt,a2的类型是int,别名只在代码中存在的,编译完成别名类型就不存在了。
// 将NewInt定义为int类型
type NewInt int
var a NewInt
//取别名
type IntAlias = int
var a2 IntAlias
关键字与标识符
Go语言关键字有如下25个:
标识符是指Go语言对各种变量、方法、函数等的命名,需要由字母、下划线、和数字组成,且第一个必须是字符。需要注意的是Go语言中,变量、函数、常量的首字母大写,则表示它可以被其他包访问(类似java的public);如果是小写,则表示只能在本包中使用(类似java的private)。Go语言有如下特殊字符,不能当做变量使用。
参考书籍:
Go语言入门教程,Golang入门教程(非常详细)
有疑问加站长微信联系(非本文作者)