go学习笔记方法定义

定义

方法总是绑定对象实例,并隐式将实例作为第一实参
只能为当前包内命名类型定义方法
参数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}
}
坚持原创技术分享,您的支持将鼓励我继续创作!