2.8 GO 参数传递
简单将GO中参数传递分为三类
数字、字符、字符串等类型
结构体
方法
GO的方法本身就是地址的入口,打印一个方法输出的是这个方法的地址
func test_func(){
//0x488a30
fmt.Printf("func address: %v \n",test_func)
//下面这行报错: cannot take the address of test_func
fmt.Printf("func address: %v \n",&test_func)
}
并且在GO语言中没法再对一个方法取地址&,之所以强调GO的方法,是因为在C语言中可以对方法取地址,但取出来的地址还是方法的入口地址,与方法本身的地址一致,这是语言设计的不同
除了方法,剩下的变量,包括结构体、数据、字符、字符串等变量,注意是变量,都可以取地址,可以作为参数传递给方法,其方式有两种
值传递与地址传递
结构体
结构体与其他基本类型又有所不同,结构体的参数,不管是地址传递还是值传递,在使用上没有区别
type Event struct{
ID int
Title string
Cmd string
Res string
} func InitEvent(e Event){
e.ID = 1
e.Title = "mysql实例崩溃后,第一次尝试重启"
e.Cmd = "/etc/init.d/mysql restart"
e.Res = "success"
} func InitEvent2(e *Event){
e.ID = 1
e.Title = "mysql实例崩溃后,第一次尝试重启"
e.Cmd = "/etc/init.d/mysql restart"
e.Res = "success"
}
比如InitEvent方法的参数类型一个是值传递,一个是地址传递,但在使用时,都是对象.属性,用法是一致,这一点与其他的一些语言不同;
GO中对结构体取地址的用法,非常非常地普遍,并且GO建议这么做(因为性能高),若无特殊场景需要,结构的传递基本全是以地址的方式进行的,比如你在看一些GO程序的源码时,凡是看到带*的变量,可以全部认为,这就是一个结构体。
GO语言说自己的值传递是一大特色,这个……这个比如在Java中,复合类型默认就是地址传递,方法中对一个对象属性的修改后,方法外对象属性值永久性变化;
在GO中如果使用值传递的方式,在方法修改结构体这种复合类型,方法外结构体属性不会变化;从这一点讲,GO并不一个完全面向对象的语言,它是面向过程与面向对象的结合。
基本类型
基本类型值传递和地址传递在使用上要有所区别
func test_var(j *int){
var i int = 1
//0xc000012068
fmt.Printf("i address: %v \n",unsafe.Pointer(&i))
//0xc000074010
fmt.Printf("j address: %v \n",j)
//9
fmt.Printf("j address: %v \n",*j)
}
基本类型,地址传递输出的就是16进制的地址,而不是变量值本身,取其值要使用*符号,*j = 1,表示将1写入j变量所在的地址;
这一点,几乎所有的语言处理方法是一致的,需要注意的是GO的字符串
在GO中字符串可以归到甚至类型这一类型中,GO中对字符中处理都是将字符串本身作为参数传递到一个方法中进行的,比如,
fmt.Println(strings.Contains("seafood", "foo")) //true
strInt64 := strconv.FormatInt(id64, 10)
这一点与C语言是一致的,而在面向对象的语言(比如Java),字符串本身就可以包含常用的字符处理方法,比如"123".equals("123")
package main import (
"fmt"
"unsafe"
) //unsafe.Pointer() 函数来查看一个变量的内存地址 func test_var(j *int){
var i int = 1
//0xc000012068
fmt.Printf("i address: %v \n",unsafe.Pointer(&i))
//0xc000074010
fmt.Printf("j address: %v \n",j)
//9
fmt.Printf("j address: %v \n",*j)
} func test_string(s *string){
fmt.Printf("s address: %v \n",*s) //abc
fmt.Printf("s address: %v \n",s) //
fmt.Printf("s address: %v \n",unsafe.Pointer(&s))
} type Event struct{
ID int
Title string
Cmd string
Res string
} func InitEvent(e Event){
e.ID = 1
e.Title = "mysql实例崩溃后,第一次尝试重启"
e.Cmd = "/etc/init.d/mysql restart"
e.Res = "success"
} func InitEvent2(e *Event){
e.ID = 1
e.Title = "mysql实例崩溃后,第一次尝试重启"
e.Cmd = "/etc/init.d/mysql restart"
e.Res = "success"
} func test_struct(){
e1 := Event{ID:0}
InitEvent(e1)
fmt.Printf("e1 address: %v \n",e1) InitEvent2(&e1)
fmt.Printf("e1 address: %v \n",e1)
} func test_func(){
//0x488a30
fmt.Printf("func address: %v \n",test_func)
//下面这行报错: cannot take the address of test_func
//fmt.Printf("func address: %v \n",&test_func)
} func main(){
//var j = 9
//test_var(&j)
ss := "abc"
test_string(&ss)
//test_struct() //test_func()
}
函数作为参数传递
GO方法也可以作为参数传递,但就没有值传递与地址传递这一说法了
package main import (
"fmt"
) //声明了一个函数类型
type testInt func(int) bool func isOdd(integer int) bool {
if integer%2 == 0 {
return false
}
return true
} func isEven(integer int) bool {
if integer%2 == 0 {
return true
}
return false
} //声明的函数在这个地方当做了一个参数
func filter(slice []int, f testInt) []int {
var result []int
for _, value := range slice {
if f(value) {
result = append(result, value)
}
}
return result
}
func main() {
slice := []int{1, 2, 3, 4, 5, 7}
fmt.Println("slice = ", slice)
//将函数当做值来传递
odd := filter(slice, isOdd)
fmt.Println("奇数是:", odd)
//将函数当做值来传递
even := filter(slice, isEven)
fmt.Println("偶数是:", even)
}
数组与切片
数组与切片参数传递相当于地址传递
package main import (
"fmt"
) func t1(){
var aa [3]int
for i:=0;i<3;i++ {
aa[i] = i+10
}
fmt.Println(aa)
ar := t2(aa) //[10 9 12]
t2(ar)
} func t2(ar [3]int) [3]int{
fmt.Println(ar)
ar[1]=9
return ar
} func s1(){
var ss []int
for i:=0;i<3;i++ {
ss = append(ss,i)
}
fmt.Println(ss) var s2 []int = make([]int,3,5)
copy(s2,ss) //len=3 cap=5 slice=[0 1 2]
x := printSlice(s2) //len=3 cap=5 slice=[0 10 2]
printSlice(x)
} func printSlice(x []int) []int{
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
x[1] = 10
return x
} func main(){
t1()
//s1()
}
2.8 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=[] ...
随机推荐
- Spring的轻量级实现
作者: Grey 原文地址:Spring的轻量级实现 本文是参考公众号:码农翻身 的从零开始造Spring 教程的学习笔记 源码 github 开发方法 使用TDD的开发方法,TDD的开发流程是: 写 ...
- [JS]什么是闭包?
首先来思考一下下面的案例: function unclosure() { let count = 0 return count++ } for (let index = 0; index < 1 ...
- Flask搭建弹幕视频网站(1)
说在前面 也不知道最后能不能完成网站,所以就想把这十多天来学习到的点点滴滴记录下来.学的越来越多,所谓全栈也是需要前端基础,越来越感受到压力,但是遇到一个问题就解决一个问题,慢慢习惯之后感觉也还行.说 ...
- PowerDotNet平台化软件架构设计与实现系列(03):系统应用平台
为了复用和解耦,快速开发更多的系统和应用,我们对自己经常说的"系统"和"应用"进行更高级的提取和抽象. 十多年前入行,辗转至今,写过很多很多应用,个人喜欢分门别 ...
- [loj3501]图函数
$f(i,G)_{x}$为$x$对$i$是否有贡献,即在枚举到$x$时,$i$与$x$是否强连通 事实上,$f(i,G)_{x}=1$即不经过$[1,x)$中的点且$i$与$x$强连通 首先,当存在这 ...
- [bzoj3171]循环格
如果把这个矩阵看成一张图,题目相当于要求每一个点的入度和出度都是1(也就是有很多环),否则指向环的点就无法走回自己了将所有点拆成两个,S向原来的点流(1,0)的边,拆出来的点向T连(1,0)的边,然后 ...
- [IIS]文件夹权限
发布完iis,默认的 Application Pool 没有权限访问文件夹. 可以给项目文件夹添加用户权限. 右键 - "属性" - "安全" - " ...
- 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)
洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\).我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...
- DTOJ 3987: 数学课
题目描述 wzy又来上数学课了-- 虽然他很菜,但是数学还是懂一丢丢的.老师出了一道题,给定一个包含$n$个元素的集合$P=1,2,3--n$求有多少集合$A \subseteq P$,满足$x \i ...
- web性能测试工具——http_load
http_load是一款基于Linux平台的web服务器性能测试工具,用于测试web服务器的吞吐量与负载,web页面的性能. http_load是基于linux.unix平台的一种性能测工具 它以并行 ...