golang中函数与方法

函数是golang中的`一等公民,可以作为普通变量、方法参数、方法返回值等,一般golang中函数定义如下:

func name(arg1 type1,args2 type2)(result1 type1,result2 type2){
    ....
}

也可以省略返回列表的结果名称:

func name(arg1 type1,args2 type2) (type1,type2){
    ....
}

如果返回参数只有一个,可以不用括号:

func name(arg1 type1,args2 type2) type {
    ....
}

如果参数列表的多个参数类型一样,可以简写如下形式:

func name(arg1,arg2 typea,arg3,arg4 typeb,arg5 typc) type {
    ....
}
函数的不定参数

当函数的参数个数不定数量时,可以使用不定参数类型:

func name(arg1 type1,args ...type2) type{
    ...
}

注意,不定参数必须放在参数列表的最后一位

匿名函数

所谓匿名函数,就是不定义函数名:

func test(){
    func (a int,b string) int {
		return a
	}(20,"leo")
}

也可以将匿名函数赋值给一个变量:

func testFunc(){
	testFunc := func (a int,b string) int {
		return a
	}
	testFunc(20,"leo")
}

方法

方法则是函数的基础上增加了一个接收者,方法是包含了接收者的函数,一般方法定义如下:

func (caller type)funcName(param1 typ1,param2 typ2)(type3,type4){
    .....
}

方法是golang中实现继承、多态的手段

值方法和指针方法之间有什么不同点呢?它们的不同如下所示。
  1. 值方法的接收者是该方法所属的那个类型值的一个副本。我们在该方法内对该副本的修改一般都不会体现在原值上,除非这个类型本身是某个引用类型(比如切片或字典)的别名类型。

而指针方法的接收者,是该方法所属的那个基本类型值的指针值的一个副本。我们在这样的方法内对该副本指向的值进行修改,却一定会体现在原值上。

  1. 一个自定义数据类型的方法集合中仅会包含它的所有值方法,而该类型的指针类型的方法集合却囊括了前者的所有方法,包括所有值方法和所有指针方法。

严格来讲,我们在这样的基本类型的值上只能调用到它的值方法。但是,Go 语言会适时地为我们进行自动地转译,使得我们在这样的值上也能调用到它的指针方法。

比如,在Cat类型的变量cat之上,之所以我们可以通过cat.SetName(“monster”)修改猫的名字,是因为 Go 语言把它自动转译为了(&cat).SetName(“monster”),即:先取cat的指针值,然后在该指针值上调用SetName方法。

  1. 在后边你会了解到,一个类型的方法集合中有哪些方法与它能实现哪些接口类型是息息相关的。如果一个基本类型和它的指针类型的方法集合是不同的,那么它们具体实现的接口类型的数量就也会有差异,除非这两个数量都是零。

如果方法的接收者不是指针而是一个具体类型,那么这个接收值实际上是一个值拷贝,在方法内对接收者进行修改不会影响实际的值。


type Rectangle struct {
	width int
	height int
}

func ( caller Rectangle)setWidth(width int){
	caller.width = width
}
func main() {
	rect := Rectangle{width:10,height:20}
	fmt.Println(rect.width)  // 10
	rect.setWidth(30)
	fmt.Println(rect.width)  // 10
}

可以看到,这里通过setWidth方法并没有改变实际rect的width值,而如果调整如下:


type Rectangle struct {
	width int
	height int
}

func ( caller *Rectangle)setWidth(width int){
	caller.width = width
}


func main() {
	 rect := &Rectangle{width:10,height:20}
	 fmt.Println(rect.width)  // 10
	 rect.setWidth(30)
	 fmt.Println(rect.width)  // 30
}

可以看到,这时候将接收者定义为指针类型,则通过setWidth方法能够改变rect的width值.
需要注意的是,这里我们可以不传入Rectangle的指针,而是直接传入Rectangle值,golang会自动将我们进行转化:

type Person struct {
	name string
	age int
	sex string
}
func (p *Person) setName(name string) {
	p.name = name
}
func main() {
	var p Person
	p.name="leo"

	fmt.Println(p.name)

	p.setName("han")
	fmt.Println(p.name)

}

如上,我们定义了一个Person指针的接收者的方法,但是调用传入的是一个Person的值类型,但是依然可以起作用。

那么方法和函数有什么区别呢:

  1. 首先函数是不支持类似面向对象的概念,而golang中的方法,则实现了类似面向对象的概念,通过将类型绑定到一个方法上,实现了该类型的行为
  2. 函数是不允许同名的,而同名的方法则是可以允许在不同的类型上定义的。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值