面向对象
package main
import "fmt"
// 首先,Go中也有结构体,类似C++的struct/class,是面向对象的基础
type Person struct {
// struct内部只有成员变量
name string
}
// 成员函数像这样定义在struct的外部,在前面自己定义类似this/self之类的变量
// 我们称之为「receiver」(这里就是p)
// receiver只能是某种非指针类型(比如Person)或者其单层指针(*Person),多层是不行的
func (p *Person) setName(name string) {
p.name = name
}
// 传值的成员函数
// func (p Person) setName(name string) {
// p.name = name
// }
// 上面有两个setName函数,一个接受Person,一个接受*Person
// 二者只能存在一个,调用的时候也没有区别(都是「p.setName」,没有「p->setName」)
// 好像是Go自动做了转换(自动将传递进来的参数,或者说调用者,匹配receiver的类型,是否是指针)
// 二者效果上的区别也很显然了,传值和传地址的区别
// 注意,关于是使用Person还是*Person,一般会有规定:
// 所有的成员函数,必须统一,要么都使用Person,要么都使用*Person
// 我觉得:不管什么情况,全用指针不就行了?不用担心复制效率的问题,统一
// 除了下面的一种情况
// 实际上这里不需要修改p的内容
// 但是为了统一还是使用了指针*Person
func (p *Person) sayHi() {
fmt.Println("Hi, I am", p.name)
}
func main() {
p := Person{
name: "A",
}
p.setName("B")
p.sayHi()
// ce: cannot call pointer method setName on Person
// 临时变量是不能取地址的,这时候receiver用指针就不方便了(当然,这不是什么重大缺陷)
// Person{"X"}.setName("Y")
// 但是注意,这样是可以的
// 临时变量取了地址,还可以正常使用
pp := &Person{"X"}
pp.setName("Y")
pp.sayHi()
}