方法
一个方法就是一个包含了接收者(receiver)的函数,接收者可以是命名类型或者结构体类型的一个值或者是一个指针,但不能是接口类型。方法所属的类型会通过其声明中的接收者声明体现出来
我们可以把结构体类型中的一个字段看作是它的一个属性或者一项数据,再把隶属于它的一个方法看作是附加在其中数据之上的一个能力或者一项操作。将属性及其能力(或者说数据及其操作)封装在一起,是面向对象编程 (Object-oriented Programming)的一个主要原则
在 Go 中,类型的代码和绑定在它上面的方法的代码可以不放置在一起,它们可以存在在不同的源文件,但必须属于同一个包
格式
func (receiver type) name(parameter-list) (return-list) {}
type Point struct{ X, Y float64 }
// traditional function
func Distance(p, q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
// same thing, but as a method of the Point type
func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
p := Point{1, 2}
q := Point{4, 6}
fmt.Println(Distance(p, q)) // "5", function call
fmt.Println(p.Distance(q)) // "5", method call
值方法
接收者类型是非指针的自定义数据类型的方法
指针方法
接收者类型是指针类型的方法
值方法和指针方法的区别?
- 值方法的接收者是该方法所属的那个类型值的一个副本。我们在该方法内对该副本的修改一般都不会体现在原值上,除非这个类型本身是某个引用类型(比如切片或字典)的别名类型;而指针方法的接收者,是该方法所属的那个基本类型值的指针值的一个副本。我们在这样的方法内对该副本指向的值进行修改,却一定会体现在原值上
- 一个自定义数据类型的方法集合中仅会包含它的所有值方法,而该类型的指针类型的方法集合却包括所有值方法和所有指针方法
*非接口的任意类型 T 都能够调用 T 的方法吗?
一个 T 类型的值可以调用 *T 类型声明的方法,当且仅当 T 是可寻址的
方法和函数的区别?
| 区别 | 函数 | 方法 |
|---|---|---|
| 定义和声明 | 独立于特定类型,可在任何作用域内定义 | 与特定类型关联,定义在类型内部 |
| 调用 | 函数名 + 参数 | 实例名 + 方法名 + 参数 |
| 参数 | 在函数定义中声明 | 接收者作为第一个参数,后面是其他参数 |
| 可见性 | 首字母大写函数在其他包可见 | 首字母大写类型和方法在其他包可见 |
| 作用域 | 包级别或局部作用域内可用 | 定义类型的包内可用 |
| 特定性 | 通用的代码块 | 特定类型的操作,可访问类型数据 |
| 适用场景 | 通用逻辑封装 | 操作类型数据,提供高级别抽象 |