美文网首页Golang 指南程序员
(译)Go 语言中没有引用传递

(译)Go 语言中没有引用传递

作者: 谢烟客 | 来源:发表于2017-09-04 13:33 被阅读969次

原文链接:There is no pass-by-reference in Go

我之前关于指针的那篇帖 引起了很多关于引用传递的争议。这篇帖子算是对这些争议的回应吧。

首先要清楚的是:Go 语言中没有引用变量,所以 Go 语言就没有引用传递的函数调用的语法。

什么是引用变量?

在像 C++ 这样的语言中你可以给一个已经存在的变量定义一个别名,这个别名就被称为引用变量。

#include <stdio.h>

int main() {
        int a = 10;
        int &b = a;
        int &c = b;

        printf("%p %p %p\n", &a, &b, &c); // 0x7ffe114f0b14 0x7ffe114f0b14 0x7ffe114f0b14
        return 0;
}

你可以看到上面 a、b、c 都指向了相同的内存地址,向 a 写入数据将会更改 b、c 的内容。这当你想在不同作用域(即函数调用)里定义引用变量的时候就显得十分的关键。

Go 语言中并没有引用变量

与 C++ 不同,Go 语言中每一个定义的变量都占据一个唯一的内存地址

dave 原来的例子我觉得可能跟上面 C++ 的例子对比不是很突出,所以我改了一下

package main

import (
    "fmt"
)

func main() {
    var a int
    var b = &a
    var c = &a

    fmt.Println(&a, &b, &c) //0xc0420361d0 0xc04204e018 0xc04204e020
}

在 Go 语言中,不可能创建 2 个变量而这 2 个变量却拥有相同的内存地址。Go 语言是允许创建 2 个变量它们的内容是同一个指向相同地址的指针,但是这与两个变量共享同一个内存地址完全是两回事。

package main

import "fmt"

func main() {
        var a int
        var b, c = &a, &a
        fmt.Println(b, c)   // 0x1040a124 0x1040a124
        fmt.Println(&b, &c) // 0x1040c108 0x1040c110
}

在这个例子中 b、c 持有的相同的值是 a 的地址,然而 b、c 他们自己的存储则存储在各自唯一的地址中的,更新 b 的内容 是不会对 c 的内容产生影响的。

但 Maps 与 Channels 是引用变量总该对了吧?

错! Maps 与 Channels 依然不是引用变量。如果他们是引用变量,那么下面这段程序将打印 false.

package main

import "fmt"

func fn(m map[int]int) {
        m = make(map[int]int)
}

func main() {
        var m map[int]int
        fn(m)
        fmt.Println(m == nil)
}

如果 m 像 C++ 那样是引用变量,定义在 fn 中的 m 与 定义在 main 中的 m 应该占用同一个内存地址,但是因为在 fn 中的赋值操作,并没有影响到 main 中 m 的值,所以我们可以看出 map 并不是引用变量。

结论:

Go 语言中并没有引用传递,因为在 Go 语言中连引用变量也没有。

相关文章

  • (译)Go 语言中没有引用传递

    原文链接:There is no pass-by-reference in Go 我之前关于指针的那篇帖 引起了很...

  • 面试题(一)

    1. Go 语言参数传递是值传递还是引用传递 Go 语言中所有的传参都是值传递,都是一个副本,一个拷贝。因为拷贝的...

  • golang 笔记

    1、go语言只有值传递,没有引用传递。但可以用指针方式实现引用传递 定义:

  • Go语言学习笔记(三)

    指针 Go的指针不能运算 参数传递 Go的参数传递是值传递(值传递:开辟新的空间,拷贝传递参数的值,引用传递:引用...

  • 真的要用引用传参吗?

    最近在写Go语言,Go没有引用。然后给我了一些启发,就把17年的引用基础的笔记翻出来,和函数的值传递和引用传递合在...

  • Go 语言程序设计——集合类型(1)

    Go语言的所有内置类型:数组、切片和映射 值、指针和引用类型 值在传递给函数或者方法的时候会被复制一次 Go语言中...

  • 【golang】3.0 指针、数组、range关键字、Slice

    指针 指针在go语言中是一个很重要的概念,但比c语言简单多了。 指针简单在:指针不能运算参数传递:值传递还是引用传...

  • go引用类型

    go引用类型 值类型   go语言中的赋值操作都是值传递,也就是会将变量完整的复制一份,一般的解决思路是使用指针 ...

  • python3 参数中的陷阱,可变对象和不可变对象

    介绍引用传递 python只允许使用引用传递, 不存在其他语言中的值传递。引用传递即引用内存地址, 无论是赋值还是...

  • 我与python学习36

    在Python 语言中,对象是通过引用传递的。

网友评论

本文标题:(译)Go 语言中没有引用传递

本文链接:https://www.haomeiwen.com/subject/ubwfjxtx.html