Golang 中的引用传递与值传递

aside section ._1OhGeD · · 3959 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一直以为自己了解了引用传递,没想到再次打破了自己的认知,所以开一篇文章,来记录一下到目前所知(本人不敢说自己已经完全掌握了)。
从书中了解到,map,slice 都是引用传递。有以下场景需要区分。

Map

变量赋值与改变其中某个元素的值

func main() {
    a := map[string]string{"a": "a"}
    newA := a
    for key, _ := range a {
        if key == "a" {
            a[key] = "A"
        }
    }
    fmt.Println(a)    // map[a:A]
    fmt.Println(newA) // map[a:A]

    a = map[string]string{}
    fmt.Println(a)    // map[]
    fmt.Println(newA) // map[a:A]
}

结论:

  • 变量赋值后,改变旧变量(a)的某个元素的值,新变量(newA)对应的元素也会改变。
  • 变量赋值后,旧变量(a)重新赋值,新变量(newA)的值并不变。

推测:

  • 变量赋值是改变了变量的地址指向,而不是将对应的值改为新值。

作为函数参数与赋值或改变一个元素的值

func main() {
    a := map[string]string{"a": "a"}
    b := map[string]string{"b": "b"}

    passAsParams(a, b)

    fmt.Println(a) // map[a:a m:m]
    fmt.Println(b) // map[b:b]
}

func passAsParams(m, n map[string]string) {
    m["m"] = "m"
    n = map[string]string{
        "n": "n",
    }
}

结论:

  • 作为函数参数传入时,修改其中一个元素或者直接赋一个新值,都会改变函数外的值。

推测:

  • 作为函数参数传入时,传入的是个引用地址,对于在地址上的赋值,会更新函数外的值。

Slice

变量赋值与改变一个元素的值

func main() {
    a := []string{"a", "b", "c", "d"}
    b := a
    c := a[0:3]

    d := []string{"d"}
    e := d
    d = []string{"g", "h"}

    a[1] = "f"

    fmt.Println(a) // [a f c d]
    fmt.Println(b) // [a f c d]
    fmt.Println(c) // [a f c]
    fmt.Println(d) // [g h]
    fmt.Println(e) // [d]
}

结论:

  • (a、b、c 比较) 对于切片旧变量(a),赋值给新变量(b)或取切片的切片给新变量(c),改变旧变量的某一个元素的值后,新变量的值都变化。
  • (用两变量 d 与 e 比较)对于切片旧变量(d),赋值给新变量(e),旧变量(d)重新赋一个立即数的切片后,新变量(e)不变。

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section ._1OhGeD

查看原文:Golang 中的引用传递与值传递

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3959 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传