欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Go 多变量赋值时注意事项

程序员文章站 2022-12-21 13:03:12
说到多变量赋值时,先计算所有相关值,然后再从左到右依次赋值,但是这个规则不适用于python我们来看一例: 输出结果: 有的朋友会认为,结果不应该是这样么?(但是python下输出的结果却是下面的)? 事实并如此,我们来看赋值顺序这段的理解: 同样的多变量赋值却不适用于python. 另外:我们要注 ......

说到多变量赋值时,先计算所有相关值,然后再从左到右依次赋值,但是这个规则不适用于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变量使用中遇到的各种奇怪的“坑”,请留下宝贵滴足迹,欢迎拍砖留言.