Skip to content

Latest commit

 

History

History
76 lines (53 loc) · 2.6 KB

特别说明.md

File metadata and controls

76 lines (53 loc) · 2.6 KB

特别说明

要区分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不行。

总之要转换思想,Python中修改变量的值可以通过其他变量间接修改,因为Python的变量只是标签,但是Go中变量是分配了内存的,想修改,只能通过修改自身的值。