Go语言对比 C++引用传参
这篇文章主要介绍了Go 到底有没有引用传参(对比 C++ ),需要的朋友可以参考下
C++ 中三种参数传递方式
值传递:
最常见的一种传参方式,函数的形参是实参的拷贝,函数中改变形参不会影响到函数外部的形参。一般是函数内部修改参数而又不希望影响到调用者的时候会采用值传递。
指针传递
形参是指向实参地址的一个指针,顾名思义,在函数中对形参指向的内容操作,实参本身会被修改。
引用传递
在 C++ 中,引用是变量的别名,实际上是同一个东西,在内存中也存在同一个地址。换句话说,不管在哪里对引用操作,都相当直接操作被引用的变量。
下面看 demo:
#include <iostream> //值传递 void func1(int a) { std::cout << "值传递,变量地址:" << &a << ", 变量值:" << a << std::endl; a ++ ; } //指针传递 void func2 (int* a) { std::cout << "指针传递,变量地址:" << a << ", 变量值:" << *a << std::endl; *a = *a + 1; } //引用传递 void func3 (int& a) { std::cout << "指针传递,变量地址:" << &a << ", 变量值:" << a << std::endl; a ++; } int main() { int a = 5; std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl; func1(a); std::cout << "值传递操作后,变量值:" << a << std::endl; std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl; func2(&a); std::cout << "指针传递操作后,变量值:" << a << std::endl; std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl; func3(a); std::cout << "引用传递操作后,变量值:" << a << std::endl; return 0; }
输出结果如下:
变量实际地址:0x28feac, 变量值:5
值传递,变量地址:0x28fe90, 变量值:5
值传递操作后,变量值:5
变量实际地址:0x28feac, 变量值:5
指针传递,变量地址:0x28feac, 变量值:5
指针传递操作后,变量值:6
变量实际地址:0x28feac, 变量值:6
指针传递,变量地址:0x28feac, 变量值:6
引用传递操作后,变量值:7
Go 中的参数传递
上面介绍了 C++ 的三种参数传递方式,值传递和指针传递容易理解,那么 Go 是不是也有这些传参方式呢?这引起过争论,但是对比 C++ 的引用传递的概念,我们可以说,Go 没有引用传递方式。为什么这么说,因为 Go 没有变量的引用这一概念。但是 Go 有引用类型,这个稍后再解释。
先看一个 Go 传值和传指针的例子:
package main import ( "fmt" ) func main() { a := 1 fmt.Println( "变量实际地址:", &a, "变量值:", a) func1 (a) fmt.Println( "值传递操作后,变量值:", a) fmt.Println( "变量实际地址:", &a, "变量值:", a) func2(&a) fmt.Println( "指针传递操作后,变量值:", a) } //值传递 func func1 (a int) { a++ fmt.Println( "值传递,变量地址:", &a, "变量值:", a) } //指针传递 func func2 (a *int) { *a = *a + 1 fmt.Println( "指针传递,变量地址:", a, "变量值:", *a) }
输出结果如下:
变量实际地址: 0xc04203c1d0 变量值: 1
值传递,变量地址: 0xc04203c210 变量值: 2
值传递操作后,变量值: 1
变量实际地址: 0xc04203c1d0 变量值: 1
指针传递,变量地址: 0xc04203c1d0 变量值: 2
指针传递操作后,变量值: 2
可以看出,Go 基本类型的值传递和指针传递和 C++ 并没有什么不同,但是它没有变量的引用这一概念。那 Go 的引用类型怎么理解呢?
Go 的引用类型
在 Go 中,引用类型包含切片、字典、通道等。以切片为例,传切片是传引用么?
举个例子:
package main import ( "fmt" ) func main() { m1 := make([]string, 1) m1[0] = "test" fmt.Println("调用 func1 前 m1 值:", m1) func1(m1) fmt.Println("调用 func1 后 m1 值:", m1) } func func1 (a []string) { a[0] = "val1" fmt.Println("func1中:", a) }
输出结果如下:
调用 func1 前 m1 值: [test]
func1中: [val1]
调用 func1 后 m1 值: [val1]
函数中对切片做出的修改影响了实际参数的值。是不是说这事引用传递?
其实并不是,要回答这个问题,首先得搞清楚调用函数切片 m1 到底有没有改变。首先我们要认清楚切片的本质。
一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度。
也就是说,上面我们打印的并不是切片本身,而是切片指向的数组。再举个例子,验证一下切片到底有没有发生变化。
package main import ( "fmt" ) func main() { m1 := make([]string, 1) m1[0] = "test" fmt.Println("调用 func1 前 m1 值:", m1, cap(m1)) func1(m1) fmt.Println("调用 func1 后 m1 值:", m1, cap(m1)) } func func1 (a []string) { a = append(a, "val1") fmt.Println("func1中:", a, cap(a)) }
输出结果如下:
调用 func1 前 m1 值: [test] 1
func1中: [test val1] 2
调用 func1 后 m1 值: [test] 1
这个结果说明,调用前后切片并没有发生变化。之前例子中所谓的“变化”其实是切片中指向数组的指针指向的数组的元素发生了变化,这句话可能比较拗口,但实际如此。再次证明,引用类型的传参不是 pass-by-reference 。
想透彻的了解 一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度这句话,有兴趣可以看这篇文章:http://www.jb51.net/kf/201604/499045.html。学习一下切片的内存模型。
总结
总结很简单,语言也需要透过现象看本质。还有本文的结论需要记住:
There is no pass-by-reference in Go.
以上是Go语言对比 C++引用传参的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

众所周知,iPhone是最人性化的电子产品之一,其中一个原因是它可以轻松地根据您的喜好进行个性化设置。在个性化设置中,您可以更改语言,这与您在设置iPhone时选择的语言不同。如果您对多种语言熟悉,或者您的iPhone语言设置错误,您可以按照我们下面解释的方法进行更改。如何更改iPhone的语言[3种方法]iOS允许用户在iPhone上自由切换首选语言,以适应不同的需求。您可以更改与Siri的交互语言,方便与语音助手进行沟通。同时,在使用本地键盘时,您可以轻松地在多种语言之间切换,提高输入效率。

当前被币圈看好的潜力币除了SOL币还有BCH币,SOL是Solana区块链平台的原生代币,BCH是BitcoinCash项目的代币,它是比特币的一个分叉货币。因为具有不同的技术特点、应用场景和发展方向,投资者在二者之前做出选择也比较困难,就想通过分析SOL币和BCH那个更有潜力?再进行投资。但币种的比较是要根据市场、发展前景、项目实力等方面综合分析的。接下来小编为大家详细说说。SOL币和BCH那个更有潜力?相较而言SOL币更有潜力,确定SOL币和BCH那个更有潜力是一个复杂的问题,因为这取决于许

在当今智能手机市场上,消费者面临着越来越多的选择。随着科技的不断发展,手机厂商推出了越来越多的型号和款式,其中Vivox100和Vivox100Pro无疑是备受关注的两款产品。两款手机均来自知名品牌Vivox,但在功能、性能和价格上却有着一定的区别,那么在面对这两款手机时,究竟哪个更值得购买呢?Vivox100和Vivox100Pro在外观设计上有着明显的差

电视盒子作为连接互联网和电视的重要装置,近年来变得越来越受欢迎。随着智能电视的普及,消费者对天猫、小米、中兴和华为等电视盒子品牌越来越青睐。为了帮助读者选择最适合自己的电视盒子,本文将深入对比这四款电视盒子的特点和优势。一、华为电视盒子:智能影音体验卓越能够提供流畅的观影体验,华为电视盒子拥有强大的处理器和高清画质。如在线视频,并且内置了丰富的应用程序,音乐和游戏等,它支持多种音频和视频格式。华为电视盒子还具备语音控制功能,同时,使操作更加便捷。可以轻松将手机上的内容投射到电视屏幕上,它的一键投

Windows10与Windows11性能对比:哪个更胜一筹?随着科技的不断发展和进步,操作系统也在不断更新和升级。微软公司作为全球最大的操作系统开发商之一,其发布的Windows系列操作系统一直备受用户关注。在2021年,微软发布了Windows11操作系统,这引发了广泛的讨论和关注。那么,究竟Windows10与Windows11在性能方面有何不同,哪个

有时候我们再刚刚入手安装好电脑系统之后发现系统时英文的,遇到这种情况我们就需要把电脑的语言改成中文,那么win10系统里面该怎么把电脑的语言改成中文呢,现在就给大家带来具体的操作方法。win10电脑语言怎么改成中文1、打开电脑点击左下角的开始按键。2、点击左侧的设置选项。3、打开的页面选择“时间和语言”4、打开后,再点击左侧的“语言”5、在这里就可以设置你要的电脑语言。

标题:Go语言与其他编程语言的性能对比及优劣势随着计算机技术的不断发展,编程语言的选择越来越关键,其中性能是一个重要的考量因素。本文将以Go语言为例,与其他常见的编程语言进行性能对比,并分析各自的优劣势。一、Go语言概述Go语言是由Google开发的一门开源编程语言,具有快速编译、高效并发、简洁易读等特点,适合用于开发网络服务、分布式系统、云计算等领域。Go

Vivox100和Vivox100Pro对比评测:你更倾向哪款?随着智能手机的不断普及和功能的日益强大,人们对手机配件的需求也日渐增长。作为手机配件中不可或缺的一部分,耳机在人们的日常生活和工作中扮演着重要的角色。而在众多耳机品牌中,Vivox100和Vivox100Pro是备受关注的两款产品。今天,我们将对这两款耳机进行详细的对比评测,看看它们的优势和劣势
