总结自:Go程序设计语言
- 1 短变量声明
//声明变量
var i, j, k int // int int int
var b, f, s = true, 2.3, "four" // boolean ,float64,string
fmt.Println(i, j, k, b, f, s)
var f,err=os.Open(name)// os.open 返回一个文件和一个错误
//短变量可以用来声明和初始化局部变量
//使用 name:= expression 而name的类型由expression决定
i := 100 //int
var boiling float64 = 100 // float64
var names []string
var err error
println(i, boiling, names, err) // 100 +1.000000e+002 [0/0]0x0 (0x0,0x0)
//多个变量
i,j := 0,1 // 声明且赋值
i ,j = j , i // 交换i和j的值
- 2 指针
int a :一个int类型,名称叫a
int* a:一个整形的指针,名称叫a
int *a:一个指向整型的地址,名称叫a(一级指针,表示a所指向的地址里面存放的是一个int类型的值)
//指针
// 指针的值是一个变量的地址,一个指针指代表了值所保存的位置,但是并不是所有的值都有地址,但是所有的变量都有值,也即都有指针
x := 1 // 声明赋值
p := &x //获取指针
println(p) //0xc000038770
println(*p) //1 *Point => 变量
*p = 2 //对指针所指向的值进行赋值
println(x) //2
var a, b int
println(&a == &a, &a == &b, &a == nil) //true false false
i := f(3)
println(i) //0xc000038768
//每次调用都是不同的值
println(f(1) == f(1)) // false
i2 := incr(p)
println(i2) //3
//传入int值,得到指针
func f(a int) *int {
return &a
}
//传入指针,得到值,通过指针操作数值变化,不修改指针
func incr(a *int) int {
*a++ //递增指针指向的值, 指针本身不变
return *a
}
可以简单理解为,每次使用变量的地址或者复制指针,创建了新的别名或者方式来标记同一变量
v:=1
p=&v
println(*p) // 1
比如: *p是v的别名
- 3 new函数
new函数是另一种创建变量的方式,使用的是内置的new函数
表达式new(T)
创建一个未命名的T类型变量,初始化为T类型的零值,并返回其地址(地址类型为*T
)
p := new(int) // *int类型的p,指向未命名的int变量
fmt.Println(*p) // 0
*p = 2
fmt.Println(*p) // 2
func newInt() *int {
return new(int)
}
func newInt2() *int {
var dummy int
return &dummy
}
a := new(int)
b := new(int)
fmt.Println(a == b) //false
// *p=2
i := delta(*p, 2)
println(i) // 0
func delta(old, new int) int {
return new - old
}
- 4 变量的生命周期
生命周期指在程序执行过程中变量存在的时间段.
包级别变量的生命周期是整个程序的执行时间
var global *int
func f1() {
var x int
x=1
global = &x
}
func g() {
y := new(int)
*y =1
}
这里的x
使用的是堆空间,f1函数返回以后还可以从global
变量访问,尽管global
声明为一个局部变量,这种情况我们成为逃逸
而g函数执行完毕后,y则不能进行访问,可以回收,