首页 > 试题

方式和方法的区别

更新时间:2022-12-07 04:31:19 阅读: 评论:0

广西北部湾高级中学-生命的长河


2022年12月7日发(作者:五一节图片带祝福)

Go函数和⽅法的区别

在Go语⾔中,函数和⽅法不太⼀样,有明确的概念区分。其他语⾔中,⽐如Java,⼀般来说函数就是⽅法,⽅法就是函数,但是

在Go语⾔中,函数是指不属于任何结构体、类型的⽅法,也就是说函数是没有接收者的;⽽⽅法是有接收者的,我们说的⽅法要么是

属于⼀个结构体的,要么属于⼀个新定义的类型的。

⼀、函数

函数和⽅法虽然概念不同,但是定义⾮常相似。函数的定义声明没有接收者,所以我们直接在go⽂件⾥,go包之下定义声明即可。

funcmain(){

sum:=add(1,2)

n(sum)

}

funcadd(a,bint)int{

returna+b

}

例⼦中,我们定义了add就是⼀个函数,它的函数签名是funcadd(a,bint)int,没有接收者,直接定义在go的⼀个包之下,可以直接调

⽤,⽐如例⼦中的main函数调⽤了add函数。例⼦中的这个函数名称是⼩写开头的add,所以它的作⽤域只属于所声明的包内使⽤,不能被

其他包使⽤,如果我们把函数名以⼤写字母开头,该函数的作⽤域就⼤了,可以被其他包调⽤。这也是Go语⾔中⼤⼩写的⽤处,⽐如Java

中就有专门的关键字来声明作⽤域private、protect、public等。如下例⼦中定义的Add⽅法就可以被其他包调⽤。

/*

提供的常⽤库,有⼀些常⽤的⽅法,⽅便使⽤

*/

packagelib

//⼀个加法实现:返回a+b的值

funcAdd(a,bint)int{

returna+b

}

⼆、⽅法

⽅法的声明和函数类似,他们的区别是:⽅法在定义的时候,会在func和⽅法名之间增加⼀个参数,这个参数就是接收者,这样我们

定义的这个⽅法就和接收者绑定在了⼀起,称之为这个接收者的⽅法。

typepersonstruct{

namestring

}

func(pperson)String()string{

return"thepersonnameis"+

}

留意例⼦中,func和⽅法名之间增加的参数(pperson),这个就是接收者。现在我们说,类型person有了⼀个String⽅法,现在我们看下

如何使⽤它。

funcmain(){

p:=person{name:"张三"}

n(())

}

调⽤的⽅法⾮常简单,使⽤类型的变量进⾏调⽤即可,类型变量和⽅法之前是⼀个.操作符,表⽰要调⽤这个类型变量的某个⽅法的意

思。Go语⾔⾥有两种类型的接收者:值接收者和指针接收者。我们上⾯的例⼦中,就是使⽤值类型接收者的⽰例。使⽤值类型接收者定义

的⽅法,在调⽤的时候,使⽤的其实是值接收者的⼀个副本,所以对该值的任何操作,不会影响原来的类型变量。

funcmain(){

p:=person{name:"张三"}

()//值接收者,修改⽆效

n(())

}

typepersonstruct{

namestring

}

func(pperson)String()string{

return"thepersonnameis"+

}

func(pperson)modify(){

="李四"

}

以上例⼦,打印出来的值还是张三,对其进⾏的修改⽆效。如果我们使⽤⼀个指针作为接收者,那么就会其作⽤了,因为指针接收者传

递的是⼀个指向原值指针的副本,指针的副本,指向的还是原来类型的值,所以修改时,同时也会影响原来类型变量的值。

funcmain(){

p:=person{name:"张三"}

()//指针接收者,修改有效

n(())

}

typepersonstruct{

namestring

}

func(pperson)String()string{

return"thepersonnameis"+

}

func(p*person)modify(){

="李四"

}

在调⽤⽅法的时候,传递的接收者本质上都是副本,只不过⼀个是这个值副本,⼀是指向这个值指针的副本。指针具有指向原有值的特

性,所以修改了指针指向的值,也就修改了原有的值。我们可以简单的理解为值接收者使⽤的是值的副本来调⽤⽅法,⽽指针接收者使⽤实

际的值来调⽤⽅法。在上⾯的例⼦中,有没有发现,我们在调⽤指针接收者⽅法的时候,使⽤的也是⼀个值的变量,并不是⼀个指针,如果

我们使⽤下⾯的也是可以的。

p:=person{name:"张三"}

(&p).modify()//指针接收者,修改有效

这样也是可以的。如果我们没有这么强制使⽤指针进⾏调⽤,Go的编译器⾃动会帮我们取指针,以满⾜接收者的要求。同样的,如果

是⼀个值接收者的⽅法,使⽤指针也是可以调⽤的,Go编译器⾃动会解引⽤,以满⾜接收者的要求,⽐如例⼦中定义的String()⽅法,也可

以这么调⽤:

p:=person{name:"张三"}

n((&p).String())

总之,⽅法的调⽤,既可以使⽤值,也可以使⽤指针,我们不必要严格的遵守这些,Go语⾔编译器会帮我们进⾏⾃动转义的,这⼤⼤

⽅便了我们开发者。不管是使⽤值接收者,还是指针接收者,⼀定要搞清楚类型的本质:对类型进⾏操作的时候,是要改变当前值,还是要

创建⼀个新值进⾏返回?这些就可以决定我们是采⽤值传递,还是指针传递。

三、多值返回

Go语⾔⽀持函数⽅法的多值返回,也就说我们定义的函数⽅法可以返回多个值,⽐如标准库⾥的很多⽅法,都是返回两个值,第⼀个

是函数需要返回的值,第⼆个是出错时返回的错误信息,这种的好处,我们的出错异常信息再也不⽤像Java⼀样使⽤⼀个Exception这么重

的⽅式表⽰了,⾮常简洁。

funcmain(){

file,err:=("/usr/tmp")

iferr!=nil{

(err)

return

}

n(file)

}

如果返回的值,我们不想使⽤,可以使⽤_进⾏忽略。

file,_:=("/usr/tmp")

多个值返回的定义也⾮常简单,看个例⼦。函数⽅法声明定义的时候,采⽤逗号分割,因为时多个返回,还要⽤括号括起来。返回的值

还是使⽤return关键字,以逗号分割,和返回的声明的顺序⼀致。

funcadd(a,bint)(int,error){

returna+b,nil

}

四、可变参数

函数⽅法的参数,可以是任意多个,这种我们称之为可以变参数,⽐如我们常⽤的n()这类函数,可以接收⼀个可变的参数。

funcmain(){

n("1","2","3")

}

可以变参数,可以是任意多个。我们⾃⼰也可以定义可以变参数,可变参数的定义,在类型前加上省略号…即可。如下例⼦中我们⾃

⼰定义了⼀个接受可变参数的函数,效果和n()⼀样。可变参数本质上是⼀个数组,所以我们向使⽤数组⼀样使⽤它,⽐如例⼦中

的forrange循环。

funcmain(){

print("1","2","3")

}

funcprint(a...interface{}){

for_,v:=rangea{

(v)

}

n()

}

本文发布于:2022-12-07 04:31:19,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/88/57406.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图