要区分Go语言和Python的本质区别:
Go语言是变量存的是一片内存地址,修改内容时修改的是内存地址中的内容 而python中是变量只是标签,每次修改,改变的是变量(标签)指向地方,内存中的内容没有变。
Python创建一个内容时,是先在内存中开辟相应的空间放内容,然后使用一个变量名(标签)来指向这个地方,所以多个变量之间相互赋值的时候,这些变量都指向了同一块内存空间,通过其中一个变量对内容进行修改则会改动所有的,因为都是指向了一个内容。
Go语言是先创建一个变量,根据变量的类型开辟大小的空间,再往内存中放置东西。多变量(必须是同种类型变量)之间相互赋值时,进行的是复制操作,对其中一个修改,是不会影响到其他内容的。所以Go的变量赋值很强调类型
- 某个类型的变量只能就收同种类型的数据
arr := [3]int{0,1,2}
bb := arr
fmt.Printf("arr address: %p\n",&arr)
fmt.Printf("bb address: %p\n",&bb)
fmt.Printf("bb: %d\n",bb)
arr[0] = 99
fmt.Printf("bb: %d\n",bb)
// 结果
arr address: 0xc000018240
bb address: 0xc000018260
bb: [0 1 2]
bb: [0 1 2]
Slice 等映射类型除外。
Go语言的所有方法一旦有返回值的都是重新创建了新的内容,需要使用新的变量去接收。如
arr := make([]int, 2, 16)
b := append(arr, 9) // 这里实际上是先创建了一个len为2,cap为16的[]int类型的变量并开辟了内存空间,然后接收了append函数返回的内容,arr和b不是指向的同一个内容,但是由于arr为slice类型,对arr现有内容的改变影响到b
fmt.Printf("arr address: %p\n",&arr)
fmt.Printf("bb address: %p\n",&bb)
fmt.Printf("bb: %d\n",bb)
arr[1] = 3
fmt.Printf("arr: %d\n",arr)
fmt.Printf("bb: %d\n",bb)
// 结果
arr address: 0xc00009c0c0
bb address: 0xc00009c0e0
bb: [0 0 9]
arr: [0 3]
bb: [0 3 9]
为了能够修改原值,定义函数的时候使用指针,这样一来,通过指针,修改了原先内存中的值。
func Push(s *[]int,v int){
*s = append(*s,v)
}
func Push(s *[]int, v int) int{
*s = append(*s, v)
return (*s)[len(*s)-1]
}
// 使用数组指针的时候,不需要使用*,只需要正常数组的使用方式即可,由于Go的语法糖,会自动转化为(*数组)。但是Slice不行。