Go 参数传递
Go参数传递
在面试中,经常会被问起,这门语言的参数传递是值传递还是引用传递,当然,大部分情况下我们都会提前准备,有恃无恐,但还是希望能够精益求精嘛,所以针对Go语言来分析,Go传参是值传递还是引用传递。那首先,我们先来了解什么是值传递,什么是引用传递。
值传递
值传递就是函数传递的是传进来参数的一个副本。换个说法就是函数内部修改传入参数的值是函数外部传入值得一个拷贝,所以你在函数内部对这个值进行修改也不会影响外部该参数的值,的确很难表达,看个案例:
package main
import "fmt"
func modify(a int){
a = 10
}
func main(){
a := 20
fmt.Println(a)
modify(a)
fmt.Println(a)
}
输出:
20
20
很直观,参数a在进入函数后并没有被改变,我们还可以看看两个内存地址是否相同
package main
import "fmt"
func modify(a int){
fmt.Println(&a)
a = 10
}
func main(){
a := 20
fmt.Println(&a)
modify(a)
}
输出为:
0xc000052080
0xc000052088
可以看到两个内存地址并不一样,这就对了,可以说明modify中的参数a,并不是主函数中的变量a,而是a的一个拷贝而已,所以在函数中修改的也是拷贝a的值,对函数外的这个a并没有改动。
这个时候,我们就会使用指针来修改值,指针案例:
func main() {
i:=10
ip:=&i
fmt.Printf("原始指针的内存地址是:%p\n",&ip)
modify(ip)
fmt.Println("int值被修改了,新值为:",i)
}
func modify(ip *int){
fmt.Printf("函数里接收到的指针的内存地址是:%p\n",&ip)
*ip=1
}
输出:
原始指针的内存地址是:0xc000006028
函数里接收到的指针的内存地址是:0xc000006038
int值被修改了,新值为: 1
可以看到两次内存地址也是不一样的,所以其实指针也是值传递,但是指针保存的是内存地址,而在函数中修改语句"*ip=1",其实是在修改变量i内存地址对应的值,那自然就是能够修改的。
引用传递
Go语言其实并没有引用传递,上面的例子可以证明如果内存地址不同自然就是值传递,那内存地址相同就是引用传递。
我们再通过Map类型进行验证,Map类型可以通过函数修改内容,但是他没有明显的指针。
func modify(p map[string]int){
fmt.Printf("函数里接收到map的内存地址是:%p\n",&p)
p["张三"] = 20
}
func main(){
person := make(map[string]int)
person["张三"] = 56
fmt.Printf("原始map的内存地址是:%p\n",mp)
modify(person)
fmt.Println("map值被修改了,新值为:",person)
}
输出:
原始map的内存地址是:0xc00007e018
函数里接收到map的内存地址是:0xc00007e028
map值被修改了,新值为: map[张三:20]
发现两个内存地址是不一样的,所以这又是一个值传递,那为什么没有使用指针却修改了Map的内容?
查看一下map源码
func makemap(t *rtype, cap int) (m unsafe.Pointer)
我们发现这个方法返回的是m unsafe.Pointer继续查看一下unsafe.Pointer类型是什么?
type Pointer *ArbitraryType
返回的还是一个指针,所以我们可以得出map的传递也是值传递。
结论
确认Go语言中所有的传参都是值传递。但是传递的类型如果是int、string、struct等这些,那在函数中无法修改原参数内容数据;如果是指针、map、slice、chan等这些,在函数中可以修改原参数内容数据。
Go 参数传递的更多相关文章
- js学习之函数的参数传递
我们都知道在 ECMAScript 中,数据类型分为原始类型(又称值类型/基本类型)和引用类型(又称对象类型):这里我将按照这两种类型分别对函数进行传参,看一下到底发生了什么. 参数的理解 首先,我们 ...
- kettle中含有参数传递的定时任务
(1)新建一个作业(新建->作业),并在控制面板右键: (2)设置一个命令参数: (3)把作业的参数传递给转换: (4)在转换中右键设置转换属性: (5)接收作业中设置的传递参数: (6)参数的 ...
- Java基础知识笔记(七:接口、变量作用域和参数传递)
一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...
- shell 脚本之获取命令输出字符串以及函数参数传递
在ubuntu 14.04之后,所有的U盘挂载也分用户之分,最近很多操作也和U盘有关,所以就研究了一上午shell脚本函数以及字符串操作的方法. 字符串操作: 获取他的命令输出比较简单,打个简单的比方 ...
- 【GoLang】golang 闭包 closure 参数传递的蹊跷!
结论: 闭包函数可以直接引用外层代码定义的变量, 但是,注意,闭包函数里面引用的是变量的地址, 当goroutine被调度时,改地址的值才会被传递给goroutine 函数. 介绍 go的闭包是一个很 ...
- JQuery Mobile 页面参数传递
在单页模版中使用基于HTTP的方式通过POST和GET请求传递参数,而在多页模版中不需要与服务器进行通信,通常在多页模版中有以下三种方法来实现页面间的参数传递. 1.GET方式:在前一个页面生成参数并 ...
- Java 中的值传递和参数传递
Java中没有指针,所以也没有引用传递了,仅仅有值传递不过可以通过对象的方式来实现引用传递 类似java没有多继承 但可以用多次implements 接口实现多继承的功能 值传递:方法调用时,实际参数 ...
- 【Python学习】函数参数传递方法四种(位置,关键字,默认值,包裹位置,包裹关键字传递)
1. 位置传递: #--coding:utf-8-- def send(name,address): return 'package is sent to %s, located in %s' %(n ...
- JAVA反射参数传递
引用:http://fish2700.blog.163.com/blog/static/130713192009103035723281/ 使用Method反射调用函数时,我们通常会遇到以下几种情况: ...
- [蟒蛇菜谱]Python函数参数传递最佳实践
将函数作为参数传递,同时将该函数需要的参数一起传递.可参考threading.Timer的处理方式: class threading.Timer(interval, function, args=[] ...
随机推荐
- 2019.12.11 java数组练习
class AmHW { public static void main(String[] args) { /* 统计一个公司三个销售小组中每个小组的总 销售额以及整个公司的销售额.如下所示 第一小组 ...
- rustup 使用
rustup 可以帮助我们安装不同版本的rust 编程需要的工具连,同时可以方便的进行不同版本 之间的切换,类似nodejs 的nvm,n, ruby 的 rvm python 的 venv ... ...
- C# list常用的几个操作 改变list中某个元素的值 替换某一段数据
1.改变list中某个元素的值 public class tb_SensorRecordModel { public int ID { get; set; } public decimal Value ...
- 在Visual Studio中直接编译Fluent的UDF
VS版本:Visual Studio 2013 Fluent版本:Fluent18.2 首先我们启动VS Studio中直接编译Fluent的UDF" title="在Visual ...
- _blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} pip
python2.6 get-pip.py 报错下面的错误_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} pip解决方案:# 1, 从官方git ...
- 第10组Alpha冲刺(1/4)
队名:凹凸曼 组长博客 作业博客 组员实践情况 童景霖 过去两天完成了哪些任务 文字/口头描述 学习Android studio和Java,基本了解APP前端的制作 完善项目APP原型 展示GitHu ...
- Typescript 开发环境的最佳实践
Typescript 开发环境的最佳实践 0️⃣ git init(略) 1️⃣️️ 初始化:$ yarn add -D ts-node typescript 2️⃣ 生成 tsconfig.json ...
- [转]Maven 全局配置文件settings.xml详解
原文地址:https://www.jianshu.com/p/110d897a5442 概要 settings.xml有什么用? 如果在Eclipse中使用过Maven插件,想必会有这个经验:配置se ...
- ubuntu中cmake版本升级
在网上下载一个项目,编译提示版本太低 CMake Error at CMakeLists.txt: (cmake_minimum_required): CMake 编译方式安装(需要openssl) ...
- datatables:initComplete和drawCallback比较
drawCallback: 对表的每个绘制事件执行操作非常有用 - 例如,您可能希望使用新显示的数据更新外部控件,或者启用服务器端处理,您可能希望将事件分配给新创建的元素.此回调旨在实现此目的,并将在 ...