亲宝软件园·资讯

展开

Go 多变量赋值时注意事项

周伯通的麦田 人气:1

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

加载全部内容

相关教程
猜你喜欢
用户评论