说到多变量赋值时,先计算所有相关值,然后再从左到右依次赋值,但是这个规则不适用于python
我们来看一例:
package main import "fmt" func main() { data, i := [3]string{"乔帮主","慕容复","鸠摩智"}, 0 i, data[i] = 2, "枯荣大师" fmt.Println(i, data) }
输出结果:
2 [枯荣大师 慕容复 鸠摩智]
有的朋友会认为,结果不应该是这样么?(但是python下输出的结果却是下面的)?
2 [乔帮主 慕容复 枯荣大师]
事实并如此,我们来看赋值顺序这段的理解:
1 data, i := [3]string{"乔帮主","慕容复","鸠摩智"}, 0 2 i, data[i] = 2, "枯荣大师" //注意原则:先计算所有相关值,然后再从左到右依次赋值 3 // 这里变量i 的顺序其实是(i = 0,因为上一行的变量i是0) -> (然后 i = 2), (data[i] 此时取的值是data[0],而不是data[2],也就是data[0] = 枯荣大师) 4 fmt.Println(i, data) //所以这里最终 输出 i=2,[枯荣大师 慕容复 鸠摩智]
同样的多变量赋值却不适用于python.
data,i=["乔帮主", "慕容复", "鸠摩智"],0 i, data[i] = 2, "枯荣大师" # 注意这里data[i] 已经是 data[2]了,即data[2]="枯荣大师" print(i,data) # 输出 2 ['乔帮主', '慕容复', '枯荣大师']
另外:我们要注意重新赋值与定义新同名变量的区别:再看一例:
package main func main() { name := "乔帮主" println(&name) name, age := "鸠摩智", 30 // 重新赋值: 与前 name 在同层次的代码块中,且有新的变量被定义。 println(&name, age) // 通常函数多返回值 err 会被重复使用。 { name, weight := "清风扬", 50 // 定义新同名变量: 不在同层次代码块。 println(&name, weight) } }
输出:
0xc00002bf78 0xc00002bf78 30 0xc00002bf68 50
注意:因个人机器不同,大家返回的内存引用地址可能和我的不一样,但是 这步是重点。重点在这里:
同层级相同变量的赋值,内存地址并不会改变。不同层级相同变量的赋值,其实是定义了一个新同名变量,也就是大家看到的第三行内存地址变了。
接着我们再看有点意思的一段代码(大家来找茬):
package main func main() { name := "乔帮主" println(&name) name, age := "鸠摩智", 30 // 重新赋值: 与前 name 在同 层次的代码块中,且有新的变量被定义。 println(&name, age) // 通常函数多返回值 err 会被重复使用。 name, weight := 100, 50 // 定义新同名变量: 不在同 层次代码块。 println(&name, weight, age) }
输出:
cannot use 100 (type int) as type string in assignment
原因很明显,因为上面:name := "乔帮主" 已经隐试滴申明了name 是字符串,等同于 var name string. 同层级再次赋值100为整形。这是不允许滴,
但是:重点来了,我们稍改下:
package main func main() { name := "乔帮主" println(&name) name, age := "鸠摩智", 30 // 重新赋值: 与前 name 在同 层次的代码块中,且有新的变量被定义。 println(&name, age) // 通常函数多返回值 err 会被重复使用。 { name, weight := 100, 50 // 定义新同名变量: 不在同层次代码块。 println(&name, weight, age) } }
区别就是层级发生了变化,因为{}里面的name已经是新的变量了。
好啦,到此介绍结束了。博友们有关golang变量使用中遇到的各种奇怪的“坑”,请留下宝贵滴足迹,欢迎拍砖留言.