简单将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 参数传递的更多相关文章

  1. js学习之函数的参数传递

    我们都知道在 ECMAScript 中,数据类型分为原始类型(又称值类型/基本类型)和引用类型(又称对象类型):这里我将按照这两种类型分别对函数进行传参,看一下到底发生了什么. 参数的理解 首先,我们 ...

  2. kettle中含有参数传递的定时任务

    (1)新建一个作业(新建->作业),并在控制面板右键: (2)设置一个命令参数: (3)把作业的参数传递给转换: (4)在转换中右键设置转换属性: (5)接收作业中设置的传递参数: (6)参数的 ...

  3. Java基础知识笔记(七:接口、变量作用域和参数传递)

    一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...

  4. shell 脚本之获取命令输出字符串以及函数参数传递

    在ubuntu 14.04之后,所有的U盘挂载也分用户之分,最近很多操作也和U盘有关,所以就研究了一上午shell脚本函数以及字符串操作的方法. 字符串操作: 获取他的命令输出比较简单,打个简单的比方 ...

  5. 【GoLang】golang 闭包 closure 参数传递的蹊跷!

    结论: 闭包函数可以直接引用外层代码定义的变量, 但是,注意,闭包函数里面引用的是变量的地址, 当goroutine被调度时,改地址的值才会被传递给goroutine 函数. 介绍 go的闭包是一个很 ...

  6. JQuery Mobile 页面参数传递

    在单页模版中使用基于HTTP的方式通过POST和GET请求传递参数,而在多页模版中不需要与服务器进行通信,通常在多页模版中有以下三种方法来实现页面间的参数传递. 1.GET方式:在前一个页面生成参数并 ...

  7. Java 中的值传递和参数传递

    Java中没有指针,所以也没有引用传递了,仅仅有值传递不过可以通过对象的方式来实现引用传递 类似java没有多继承 但可以用多次implements 接口实现多继承的功能 值传递:方法调用时,实际参数 ...

  8. 【Python学习】函数参数传递方法四种(位置,关键字,默认值,包裹位置,包裹关键字传递)

    1. 位置传递: #--coding:utf-8-- def send(name,address): return 'package is sent to %s, located in %s' %(n ...

  9. JAVA反射参数传递

    引用:http://fish2700.blog.163.com/blog/static/130713192009103035723281/ 使用Method反射调用函数时,我们通常会遇到以下几种情况: ...

  10. [蟒蛇菜谱]Python函数参数传递最佳实践

    将函数作为参数传递,同时将该函数需要的参数一起传递.可参考threading.Timer的处理方式: class threading.Timer(interval, function, args=[] ...

随机推荐

  1. 【解决方案】Pyinstaller打包exe策略(简单实用)

    场景说明 在业务场景中, 经常需要Python开发一些小程序/脚本/GUI界面,进行简单的项目测试或未安装Python 的小伙伴们使用. 使用Pyinstaller将Python脚本或者项目打包,生成 ...

  2. Java8新特性之Optional,如何优雅地处理空指针

    是什么 ​ 从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException)-- 每个 Java ...

  3. storm在windows下本地调试报错java.lang.UnsatisfiedLinkError cannot find rocksdbjnixxxxxxxxxx.dll

    storm启动本地集群调试时,有时会找不到rocksdbjni.dll,storm加载该库的时候会先从jkd的bin下找rocksdbjni.dll,如果找不到就从pom文件的依赖包里找,再找不到就会 ...

  4. python3下tomorow模块 @thread报语法错误def async(n, base_type, timeout=None): ^ SyntaxError: invalid syntax---解决方法

    遇见问题:python使用tomorrow实现多线程,tomorrow模块的源代码报语法错误? 这是报错信息:Traceback (most recent call last):  File &quo ...

  5. 行星万象表白墙微信小程序、社交微信小程序,后台完整,支持多区域运营,扫码体验。

    简介 中国目前大概有5000个表白墙,累计用户近3000万,是一个庞大的群体,但现在大都以微信朋友圈为基础进行信息中转,但是这种模式经营者和用户都不友好,尤其是经营者无法变现,用户无法公开评论,这些种 ...

  6. myeclipse重写快捷键

    shift+alt+s 点击Override/Implments methods

  7. [bzoj3171]循环格

    如果把这个矩阵看成一张图,题目相当于要求每一个点的入度和出度都是1(也就是有很多环),否则指向环的点就无法走回自己了将所有点拆成两个,S向原来的点流(1,0)的边,拆出来的点向T连(1,0)的边,然后 ...

  8. Java开发最实用最好用的11个技术网站

    作为一个Java开发者,学习最新技术和关注行业内容是你不断提升自我的有效手段.因此,我会特别关注一些质量高口碑好的Java技术网站,在这里分享给大家. 1.Stackoverflow Stackove ...

  9. BZOJ 3926 诸神眷顾的幻想乡

    BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...

  10. Python list的深拷贝和浅拷贝

    深拷贝和浅拷贝 列表存储数据,列表拷贝就是数据备份 浅拷贝 优点:占用内存较少 缺点:修改深层数据,会影响原数据 深拷贝 优点:修改数据,互不影响 缺点:占用内存较大 ""&quo ...