网站注册域名免费,wordpress缓存插件 w3,网站数据库有哪些,企业信息填报年报填写前言 在前面的 一文熟悉 Go 函数 文章中#xff0c;介绍了 Go 函数的声明#xff0c;函数的几种形式如匿名函数、闭包、基于函数的自定义类型和函数参数详解等#xff0c;而本文将对方法进行介绍#xff0c;方法的本质就是函数#xff0c;介绍方法的同时也会顺带对比其与函…前言 在前面的 一文熟悉 Go 函数 文章中介绍了 Go 函数的声明函数的几种形式如匿名函数、闭包、基于函数的自定义类型和函数参数详解等而本文将对方法进行介绍方法的本质就是函数介绍方法的同时也会顺带对比其与函数的不同之处。
方法 在 Go 中我们可以为任何的数据类型定义方法(指针或接口除外)现在让我们看一看方法的声明和组成部分以及与函数有什么不同之处。
type Person struct {age int
}func (p *Person) SetAge(age int) error {if age 0 {return errors.New(年龄不能小于 0 )}p.age agereturn nil
}上述代码定义了一个结构体 Person此结构体包含一个 age 属性一个 SetAge 方法此方法只作用于 Person 结构体。我们可以看到该方法包含六部分分别为
1、关键字 声明方法时必须以 func 关键字开头还记得函数的声明吗也是以这个关键字开头。 2、receiver 部分 (p *Person) 这部分在 Go 中称为 receiver 部分里面的参数称为 receiver 参数相比于函数方法与其的声明区别就在于多了这一部分。 3、方法名。 Go 推荐使用驼峰命名的方式和变量的命名规则一样首字母大写的方法名可以在包外访问小写的只能在包内访问。 4、参数列表 参数列表中声明了在方法体里所使用到的变量。参数列表位于方法名后面用括号包裹着多个参数使用逗号分隔开。 5、返回值列表 返回值为函数执行后的一个结果上述代码只有一个返回值如果有多个返回值需要用括号包裹着返回值之间用逗号分隔开。 6、方法体 大括号内就是方法体存放着方法的具体实现。
方法的调用 通过 变量.方法名(参数) 的方式对方法进行调用。例如
import (errorsfmt
)type Person struct {age int
}func (p *Person) SetAge(age int) error {if age 0 {return errors.New(年龄不能小于 0 )}p.age agereturn nil
}func main() {person : Person{}err : person.SetAge(18)if err ! nil {return}fmt.Println(person.age) // 18
}创建一个 person 变量然后调用 SetAge 函数。 Receiver 参数类型的选择 在 Receiver 部分我们可以绑定值类型也可以绑定指针类型这两种类型什么时候使用呢
如果方法体里不涉及到修改结构体变量的属性值使用值类型
type Person struct {age int
}func (p Person) GetAge() int {return p.age
}对于 GetAge 方法作用是返回年龄没有涉及到修改年龄的操作因此 receiver 部分选择 Person 类型就可以。 如果方法体里有修改结构体变量的属性值的操作使用指针类型 type Person struct {age int
}func (p *Person) SetAge(age int) error {if age 0 {return errors.New(年龄不能小于 0 )}p.age agereturn nil
}SetAge 涉及到对结构体属性值修改的操作因此 receiver 部分使用指针类型通过指针可以对所指向地址的变量进行修改操作。
方法的约束 Go 对方法声明的位置是有约束的我们不能跨越包去声明一个类型的方法根据这个特点我们可以发现
不能为基本数据类型声明方法 因为基本数据类型所定义的位置是不在我们所编码的包里面的。
不能跨越包为其他包的类型声明方法 这个是 Go 的所规定的的。
小结 本文介绍了 Go 方法的声明方式、组成部分和其与函数的不同点同时指出Receiver 参数类型在不同场景下的选择最后介绍了 Go 对方法约束的体现。