Go语言方法
方法定义
Go
语言的方法非常纯粹, 可以看作特殊类型的函数, 其显式地将对象实例或指针作为函数的第一个参数, 并且参数名可以自己指定, 而不强制要求一定是 this
或 self
。这个对象实例或指针称为方法的接收者(reciever)。
为命名类型定义方法的语法格式如下:
go
// 类型方法接收者是值类型
func (t TypeName) MethodName (ParamList ) (Returnlist) {
//method body
}
// 类型方法接收者是指针
func (t *TypeName) MethodName (ParamList) (Returnlist) {
//method body
}
说明:
t 是接收者或者叫接收器变量,官方建议使用接收器类型名 TypeName
的 第一个小写字母,而不是 self 、 this 之类的命名。例如, Socket
类型的接收器变量应该命名为 s, Connector
类型的接收器变量应该命名为 c 等; TypeName
为命名类型的类型名; MethodName
为方法名,是一个自定义标识符; ParamList
是形参列表; ReturnList
是返回值列表; 接收者的定义和普通变量、函数参数等一样,前面是变量名,后面是接收者类型。
创建方法和使用
切片方法
go
package main
import "fmt"
type SliceInt []int
// 面向对象
func (s SliceInt) Sum() int {
sum := 0
for _, i := range s {
sum += i
}
return sum
}
// 面向过程 这个函数和上面方法等价
func SliceIntSum(s SliceInt) int {
sum := 0
for _, i := range s {
sum += i
}
return sum
}
func main() {
var s SliceInt = []int{1, 2, 3, 4, 5}
fmt.Println(s.Sum()) // 面向对象的方法
fmt.Println(SliceIntSum(s)) // 面向过程的方法
}
结构体方法
处理球体时,假设您要计算其表面积和体积。在这种情况下,非常适合使用结构体和方法集。通过使用方法集,您只需创建一次计算代码,就可将其重用于任何球体。要创建这个方法集,可声明结构体 Sphere
巳再声明两个将结构体 Sphere
作为接收者的方法。
go
package main
import (
"fmt"
"math"
)
type Sphere struct {
Radius float64
}
/* 这里声明了计算球体表面积和体积的方法,并像通常那样定义函数签名。唯一不同的
是添加了一个表示接收者的参数,这里是一个指向 Sphere 实例的指针
*/
func (s *Sphere) SurfaceArea() float64 {
return float64(4) * math.Pi * (s.Radius * s.Radius)
}
func (s *Sphere) Volume() float64 {
radiusCubed := s.Radius * s.Radius * s.Radius
return (float64(4) / float64(3)) * math.Pi * radiusCubed
}
// 方法接收者参数类型为值引用
func (s Sphere) ChageRadiusValue(r float64) float64 {
s.Radius = r
return r
}
// 方法接收者参数类型为指针
func (s *Sphere) ChageRadiusPoint(r float64) float64 {
s.Radius = r
return r
}
func main() {
s := &Sphere{
Radius: 5,
}
fmt.Println(s.SurfaceArea())
fmt.Println(s.Volume())
r := 1.0
s.ChageRadiusValue(r) // 方法接收者参数类型为值引用时不会改变原始值
fmt.Println(s.Radius) // 5
s.ChageRadiusPoint(r) // 方法接收者参数类型为指针时会改变原始值
fmt.Println(s.Radius) // 1
}
指针和值之间的差别很微妙,但选择使用指针还是值这一点很简单:
- 如果需要修改原始结构体,就使用指针;
- 如果需要操作结构体,但不想修改原始结构体,就使用值.