diff --git a/day4/var.go b/day4/var.go index ba3ca48..4a84d76 100644 --- a/day4/var.go +++ b/day4/var.go @@ -19,7 +19,7 @@ func main() { // 可以使用简短变量声明 // 名字 := 表达式 - operation := 1 + 10 - 5 // 5 + operation := 1 + 10 - 6 // 5 fmt.Println(operation) // 可以十分简单的交换两个变量的值 @@ -30,5 +30,55 @@ func main() { fmt.Println("after:", number1, number2) // 6, 2 // 指针 + // 一个变量对应一个保存了变量对应类型值的内存空间。 + // 声明指令变量时 *类型为该类型的指针类型 + // 例如*int代表int指针类型,*bool为bool型的指针类型 + // &变量 代表取这个变量的地址 + // 注意: 指针类型的变量本身也具有地址,可以被&取地址操作 + var point *int = &operation + //*point 代表访问指令变量指向的变量的原始值 + fmt.Println(*point) // 5 + *point = 10 + 2 // 12 + fmt.Println(*point) // 12 + + //任何类型的指针的零值都是nil。如果p指向某个有效变量,那么p != nil测试为真。 + //指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是nil时才相等。 + var point1, point2 *int + fmt.Println(point1 == point1, point1 == point2, point1 == nil) + // true true true + point1, point2 = &operation, &operation + fmt.Println(point1 == point2) // true + + // 在Go语言中,返回函数中局部变量的地址也是安全的。 + //例如下面的代码,调用f函数时创建局部变量v,在局部变量地址被返回之后依然有效 + fun1 := func() *int { + v := 1 + return &v + } + fmt.Println(fun1() == fun1()) // false + + // 另一个创建变量的方法是调用内建的new函数。 + // 表达式new(T)将创建一个T类型的匿名变量, + // 初始化为T类型的零值,然后返回变量地址, + // 返回的指针类型为*T + point3 := new(int) // 创建一个*int类型的指针变量,指向匿名函数,此函数为int型 + *point3 = 34 + fmt.Println(*point3) // 34 + + // new()函数和普通声明指针类型的变量没有任何区别,new()更类似于语法糖 + // 下面fun2(), fun3()两个函数有着相同的行为 + fun2 := func() *int { + return new(int) + } + fun3 := func() *int { + var temp int + return &temp + } + // false 因为 两个函数申请的不同的变量 + point4, point5 := fun2(), fun3() + fmt.Println("point4 == point5:", point4 == point5) // false + // 每次调用new函数都是返回一个新的变量的地址,因此下面两个地址是不同的 + point4, point5 = new(int), new(int) + fmt.Println("point4 == point5:", point4 == point5) // false }