其实之前有自学过go的基础,但是时隔蛮久的,然后也没有去经常性的使用,现在重头开始学习啦
声明
声明语句定义了程序的各种实体对象以及部分或全部的属性。Go语言主要有四种类型的声明语句:变量(var)
、常量(const)
、类型(type)
和函数(func)
实体对象的声明。
一个Go语言编写的程序对应一个或多个以.go为文件后缀名的源文件中。每个源文件编写顺序是
- 说明该源文件是属于哪个包。
package main
- 包声明语句之后是import语句导入依赖的其它包
import "fmt"
- 然后是包一级的类型、变量、常量、函数的声明语句,包一级的各种类型的声明语句的顺序无关紧要
var x, y int
const pi = 3.14
func sayhi(){
fmt.Println("Hello")
}
变量
var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:
var 变量名字 类型 = 表达式
其中“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量。
var x int = 1
var y = 2
var i, j, k int // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string
简短变量声明
在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导
i := 100
和var形式声明语句一样,简短变量声明语句也可以用来声明和初始化一组变量:
i, j := 0, 1
请记住“:=”是一个变量声明语句,而“=”是一个变量赋值操作。
如果重复使用简短变量声明定义一个变量,那这个变量的第二次声明就是赋值
in, err := os.Open(infile)
// 这里只声明了out一个变量,err进行了赋值操作
out, err := os.Create(outfile)
简短变量声明语句中必须至少要声明一个新的变量,下面的代码将不能编译通过:
f, err := os.Open(infile)
// ...
f, err := os.Create(outfile) // compile error: no new variables
解决的方法
是第二个简短变量声明语句改用普通的多重赋值语句。
简短变量声明语句只有对已经在同级词法域
声明过的变量才和赋值操作语句等价,如果变量是在外部词法域
声明的,那么简短变量声明语句将会在当前词法域重新声明一个新的变量。
ps:
简单来说就是,简短变量声明你就当做普通声明来用,但是一般都是用在函数体内,重复声明一个变量的时候注意细节
指针
想了很久,没办法用比较通俗易懂的说法来简述,如果你跟我一样会PHP,那你就把这个指针理解为PHP中的引用就行了,直接用代码展示吧
x := 1
p := &x // p, of type *int, points to x
fmt.Println(*p) // "1"
*p = 2 // equivalent to x = 2
fmt.Println(x) // "2"
如果用“var x int”声明语句声明一个x变量,那么&x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,指针对应的数据类型是 *int
,指针被称之为“指向int类型的指针”。如果指针名字为p,那么可以说“p指针指向变量x”,或者说“p指针保存了x变量的内存地址”。同时 *p
表达式对应p指针指向的变量的值。一般 *p
表达式读取指针指向的变量的值,这里为int类型的值,同时因为 *p
对应一个变量,所以该表达式也可以出现在赋值语句的左边,表示更新指针所指向的变量的值。
var x, y int
fmt.Println(&x == &x, &x == &y, &x == nil) // "true false false"
任何类型的指针的零值都是nil
。如果p指向某个有效变量,那么p != nil测试为真。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是 nil
时才相等。
简单的函数使用指针:
func incr(p *int) int {
*p++ // 非常重要:只是增加p指向的变量的值,并不改变p指针!!!
return *p
}
v := 1
incr(&v) // side effect: v is now 2
fmt.Println(incr(&v)) // "3" (and v is 3)
new函数
另一个创建变量的方法是调用用内建的new函数。表达式new(T)将创建一个T类型的匿名变量
,初始化为T类型的零值
,然后返回变量地址
,返回的指针类型为*T。
用new创建变量和普通变量声明语句方式创建变量没有什么区别
,除了不需要声明一个临时变量的名字外,我们还可以在表达式中使用new(T)。换言之,new函数类似是一种语法糖
,而不是一个新的基础概念。
下面的两个newInt函数有着相同的行为:
func newInt() *int {
return new(int)
}
func newInt() *int {
var dummy int
return &dummy
}
变量的生命周期
变量的生命周期
指的是在程序运行期间变量有效存在的时间间隔。对于在包一级
声明的变量来说,它们的生命周期和整个程序的运行周期是一致
的。而相比之下,局部变量
的声明周期则是动态
的:每次从创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。
参考
《GO语言圣经》
有疑问加站长微信联系(非本文作者)