概念
Go语言
- 单独定义 函数
- 为 结构体 添加函数,被添加方法的结构体的变量名在 Golang 中被叫做 接收器
Go语言中 接收器
- 接收器 类型 可以是任何类型比如 int、bool、string、数组、切片 等类型的别名,甚至也可以是函数类型
- 接收器不能是一个接口类型,接口是一个抽象定义,而方法却是具体实现,如果这样做会引发一个编译错误
结构体指针内部转换
package mainimport "fmt"type person struct {name string //名字sex byte //性别, 字符类型age int //年龄}func (p person) setInfoValue() {fmt.Println("SetInfoValue")}func (p *person) setInfoPointer() {fmt.Println("SetInfoPointer")}func main() {p := &person{"mike", 'm', 18}(*p).setInfoPointer() // 把(*p)转换层p后再调用,等价于 p.setInfoValue()p.setInfoValue() // 内部做的转换, 先把指针p, 转成*p后再调用 (*p).setInfoValue()p2 := person{"tom", 'm', 18}p2.setInfoPointer() // 内部,先把p2转为为&p2再调用, (&p).setInfoPointer()// (&p2).setInfoPointer()p2.setInfoValue()}
为结构体添加方法
一般建议为值类型添加这样的方法
var (s StructType)funcName(param1 param1Type, ...)(returnVal1 returnType1, ...){ }
为结构体 StructType 添加一个函数 funcName,该函数的参数为 param1,返回值为 returnVal1,参数和返回值可以有 0 个或者任意多个。
package mainimport "fmt"type Student struct {Name stringAge intScore float64}func (p Student)print(){fmt.Println("Name =", p.Name, "Age =", p.Age) //Name = Ueumd Age = 18}func (s Student)isPass(score float64)(isPass bool){if s.Score >= score{return true}return false}func main() {var p = Student{Name: "Ueumd",Age: 18,Score: 60,}p.print()isPass := p.isPass(100)fmt.Println("IsPass =",isPass) //IsPass = false/**Name = Ueumd Age = 18IsPass = false*/}
为结构体添加方法指针接收器 (实例)
Go 语言 中 结构体 方法的接收器可以是一个 指针 类型。
如果是指针类型的接收器,那么在方法中,对结构体的修改都会生效。
var (this *StructType)funcName(param1 param1Type, ...)(returnVal1 returnType1, ...){}
为结构体 StructType 添加一个 函数 funcName,该函数的 参数 为 param1,返回值 为 returnVal1,参数和返回值可以有 0 个或者任意多个。
this是一个指针接收器,可以通过 this 对结构体成员变量的修改。
使用指针接收器的方法,可以通过指针修改成员变量的值。
package mainimport ("fmt")type Student struct {Name stringAge intScore float64}func (p Student)print(){fmt.Println("Name =", p.Name, ", Age =", p.Age) //Name = Ueumd , Age = 18}func (s Student)isPass(score float64)(isPass bool){if s.Score >= score{return true}return false}func (this Student)setName2(name string) {this.Name = name}// 使用指针接收器的方法,可以通过指针修改成员变量的值func (this *Student)setName(name string) {this.Name = name}func main() {var p = Student{Name: "Ueumd",Age: 18,Score: 60,}p.print()isPass := p.isPass(100)fmt.Println("IsPass =",isPass) //IsPass = false/**Name = Ueumd , Age = 18IsPass = false*/// 并没有改变结构体成员变量p.setName2("我是谁")p.print() // Name = Ueumd , Age = 18/**指针接书器会改变结构中成员变量所以我们可以利用这一点去实现oop*/p.setName("who am i") // Name = who am i , Age = 18p.print()}
指针接收器与非指针接收器区别
- 指针接收器 可以对成员变量进行修改
- 非指针接收器 不可以对指针变量进行修改
- 指针接收器和非指针接收器不可以重名
Should I define methods on values or pointers?
func (s *MyStruct) pointerMethod() { } // method on pointer 结构体 数组 切片func (s MyStruct) valueMethod() { } // method on value 适合基本类型
任意类型添加方法
//为内置类型 int 类型添加方法type MyInt intfunc (m MyInt)IntAbs()MyInt{if m >= 0{return m}return -m}func init() {var myInt MyInt = 10fmt.Println("IntAbs =", myInt.IntAbs()) // 10myInt = -10fmt.Println("IntAbs =", myInt.IntAbs()) // 10}
