规则:开头是字母或下划线,后面跟任意字符、数字和下划线,并区分大小写
书本P20:有25个关键字预留,还有三十几个内置的预声明的常量、类型和函数
如果一个实体在函数声明
,它只在函数局部有效
。如果声明在函数外
,则将对包里面的所有源文件可见
。
实体第一个字母的大小决定其可见性是否跨包。如果名称以大写字母开头
,它是导出的,意味这它对包外是可见和可访问
的,可以被自己包之外的其他程序所引用,如fmt包中的Printf,
包名本身总是由小写字母组成
作用域越大,所使用的名称越长
使用驼峰式风格而不是下划线
首字母缩写词如HTML,通常使用相同的大小写。
声明给一个程序实体命名,并且设定其部分或全部属性。
有四种主要的声明:
本章主要讨论变量和类型,常量在第三章,函数在第五章
函数声明包含一个名字、一个参数列表、一个可选的返回值列表,以及函数体。
格式:var name type = expression
类型和表达式可以忽略一个,但不能都忽略
如果类型省略,它的类型由初始化表达式决定;
如果表达式省略,其初始值对应类型的零值——数字是0,布尔值是false,字符串是"",接口和引用类型(slice、指针、map、通道、函数)是nil。对于数组或结构体这种复合类型,零值是其所有元素或成员的零值
Go不存在未初始化的变量
可以声明一个变量列表,选择使用对应的表达式列表进行初始化。忽略类型允许声明多个不同类型的变量
var i, j, k int //int int int
var b, f, s = true, 2.3, "four" //bool float64 string
也可以通过调用返回多个值的函数进行初始化
var f, err = os.Open(name) //返回一个文件和一个错误
格式:name := expression
name的类型由expresssion决定
因其短小、灵活,故而在局部变量的声明和初始化
中主要使用短声明。
var声明通常是为那些跟初始化表达式类型不一致的局部变量保留的,或者用于后面才对变量赋值以及变量初始值不重要的情况
i := 100
var boiling float64 = 100 //一个float64类型的变量
var name []string
var err error
var p Point
只有在对可读性有帮助的时候才适应多个初始化表达式进行变量声明
:=表示声明,而=表示赋值
i,j = j, i //交换i 和 j的值
注意:短变量声明不需要声明所有在左边的变量;如果一个变量在同一个语法块已经被声明了,则这个变量的短声明就会等同于赋值。
短变量声明最少声明一个新变量
指针的值是一个变量的地址,使用指针可以在不知道变量名字的情况下,间接读取或更新变量的值
零值是nil
指针是可比较的,两个指针当且仅当指向同一个变量或者两个都是nil的时候才相等
函数返回局部变量的地址是非常安全的
var p = f()
func f() *int{
v := 1
return &v
}
返回后v仍然存在,p指向v的地址
另一种创建变量的方式
格式:new(T)
,创建一个未命名的T类型变量,初始化为T类型的零值,并返回其地址(地址类型为 *T)
每一次调用new都会返回一个具有唯一地址的不同变量
p := new(int)
q := new(int)
fmt.Println(p == q) //"false"
该规则有个例外:两个变量的类型不携带任何信息且是零值,如struct{}或[0]int,当前实现里,它们有相同的地址
new是一个预声明的函数,不是一个关键字,所以可以被重定义为其他类型,例如:
func delta(old, new int) int{
return new - old
}
自然,在delta函数内,内置的new函数不可用
指在程序执行过程中变量存在的时间段。
包级别变量的生命周期是整个程序的执行时间
局部变量有一个动态的生命周期:每次执行声明语句时创建一个新的实体,变量一直生存到它变得不可访问
,这时它占用的存储空间被回收。
函数的参数和返回值也是局部变量,它们在其闭包函数被调用时创建
垃圾回收器判断变量是否应该被回收貌似是根可达
算法,同时局部变量还会存在逃逸现象,跟java的差不多
允许几个变量一次性被赋值
在实际更新变量前,右边所有的表达式被推演,当变量同时出现在赋值符两侧的时候这种形式特别好用,例如,当交换两个变量的值时:
x, y = y, x
a[i], a[j] = a[j], a[i]
也可以使一个普通的赋值序列变得紧凑
i, j, k = 2, 3, 5
如果表达式比较复杂,则避免使用多重赋值形式,一系列独立的语句更易读
赋值语句是显式形式的赋值,但是程序汇总很多地方的赋值是隐式的:一个函数调用隐式地将参数的值赋给对应参数的变量:一个return语句隐式地将return操作数赋值给结果变量。
复合类型的字面量表达式,如slice:
medals := []string{"gold", "sliver", "bronze"}
隐式地给每个元素赋值,等同于:
medals[0] = "gold"
medals[1] = "sliver"
medals[2] = "bronze"
两个值使用 == 和 != 进行比较与可赋值性相关:任何比较中,第一个操作数对于第二个操作数的类型必须是可赋值的,或者可以反过来赋值
type声明定义一个新的命名类型,它与某个已有类型使用同样的底层类型
格式:type name underlying-type
,
type Celsius float64
type Fahrenheit float64
虽然Celsius类型和Fahrenheit类型底层都是float64,但是他们不可以比较和合并,只能强转后再来操作
详情看P29
与java类似
详情看P30
与java类似
详情看P34