定义
方法总是绑定对象实例,并隐式将实例作为第一实参
只能为当前包内命名类型定义方法
参数receiver可任意命名。如方法中未曾使用,可省略参数名
参数receiver类型可以使T(值复制)或*T(引用或指针复制)。基类型T不能是接口或指针
不支持方法重载,receiver只是参数签名的组成部分
可用实例value或pointer调用全部方法,编译器自动转换
简单工厂模式返回对象事例(然而我没看懂)
package main
import "fmt"
type Queue struct {
elements []interface{}
}
func NewQueue() *Queue {
return &Queue{make([]interface{}, 10)}
}
func (*Queue) Push(e interface{}) error {
panic("not implemented")
}
func (self *Queue) length() int {
return len(self.elements)
}
看看receiver T和*T的区别
package main
import "fmt"
type Data struct {
x int
}
func (self Data) ValueTest() {
fmt.Printf("Value:%p\n", &self)
}
func (self *Data) PointerTest() {
fmt.Printf("Pointer:%p\n", self)
}
func main() {
d := Data{}
p := &d
fmt.Printf("Data:%p\n", p)
d.ValueTest()
d.PointerTest()
p.ValueTest()
p.PointerTest()
}
匿名字段,可以像字段成员那样访问匿名字段方法,编译器负责查找
package main
import "fmt"
type User struct {
id int
name string
}
type Manager struct {
User
}
func (self *User) Tostring() string { //receiver = &(Manager.User)
return fmt.Sprintf("User:%p, %v", self, self)
}
func main() {
m := Manager{User{1, "Tom"}}
fmt.Printf("Manager:%p\n", &m) //Manager:0xc42007e060
fmt.Println(m.Tostring()) //User:0xc42000e1a0, &{1 Tom}
}
通过匿名字段,可获得和继承类似的复用能力。依据编译器查找次序,只需在外层定义同名方法,就可以实现”override”
package main
import "fmt"
type User struct {
id int
name string
}
type Manager struct {
User
title string
}
func (self *User) Tostring() string { //receiver = &(Manager.User)
return fmt.Sprintf("User:%p, %v", self, self)
}
func (self *Manager) Tostring() string { //receiver = &(Manager.User)
return fmt.Sprintf("Manager:%p, %v", self, self)
}
func main() {
m := Manager{User{1, "Tom"}, "admin"}
fmt.Println(m.Tostring()) //Manager:0xc420014120, &{{1 Tom} admin}
fmt.Println(m.User.Tostring()) //User:0xc420014120, &{1 Tom}
}