概念
Go语言
- 单独定义 函数
- 为 结构体 添加函数,被添加方法的结构体的变量名在 Golang 中被叫做 接收器
Go语言中 接收器
- 接收器 类型 可以是任何类型比如 int、bool、string、数组、切片 等类型的别名,甚至也可以是函数类型
- 接收器不能是一个接口类型,接口是一个抽象定义,而方法却是具体实现,如果这样做会引发一个编译错误
结构体指针内部转换
package main
import "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 main
import "fmt"
type Student struct {
Name string
Age int
Score 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 = 18
IsPass = false
*/
}
为结构体添加方法指针接收器 (实例)
Go 语言 中 结构体 方法的接收器可以是一个 指针 类型。
如果是指针类型的接收器,那么在方法中,对结构体的修改都会生效。
var (this *StructType)funcName(param1 param1Type, ...)(returnVal1 returnType1, ...){}
为结构体 StructType 添加一个 函数 funcName,该函数的 参数 为 param1,返回值 为 returnVal1,参数和返回值可以有 0 个或者任意多个。
this是一个指针接收器,可以通过 this 对结构体成员变量的修改。
使用指针接收器的方法,可以通过指针修改成员变量的值。
package main
import (
"fmt"
)
type Student struct {
Name string
Age int
Score 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 = 18
IsPass = false
*/
// 并没有改变结构体成员变量
p.setName2("我是谁")
p.print() // Name = Ueumd , Age = 18
/**
指针接书器会改变结构中成员变量
所以我们可以利用这一点去实现oop
*/
p.setName("who am i") // Name = who am i , Age = 18
p.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 int
func (m MyInt)IntAbs()MyInt{
if m >= 0{
return m
}
return -m
}
func init() {
var myInt MyInt = 10
fmt.Println("IntAbs =", myInt.IntAbs()) // 10
myInt = -10
fmt.Println("IntAbs =", myInt.IntAbs()) // 10
}