方法集与表达式

Golang 表达式 :根据调用者不同,方法分为两种表现形式:

instance.method(args...) ---> .func(instance, args...)  

前者称为 method value,后者 method expression。

两者都可像普通函数那样赋值和传参,区别在于 method value 绑定实例,而 method expression 则须显式传参。

package main

import "fmt"

type User struct {
    id int
    name string
}

type Manager struct {
    User//通过组合实现继承
    title string
}

func (u *User) ToString() string {
    return fmt.Sprintf("User: %p %v\n",u, u)
}

func (m *Manager) ToString() string  {
    return fmt.Sprintf("Manager: %p %v\n",m, m)
}

func (u *User) TestPointer() {
    fmt.Printf("TestPointer %p,%v\n",u, u)
}

func (u User) TestValue(){
    fmt.Printf("TestValue %p,%v\n",&u,u)
}

func main() {
    m := Manager{User{1,"Tom"},"Administrator"}
    fmt.Println(m.ToString())
    fmt.Println(m.User.ToString())
    fmt.Println("---------------------------------")
    u := User{1,"Tom"}
    u.TestValue()//u为{1,"Tom"}
    uValue := u.TestValue//uValue为当前u的方法,复制了u的值
    u.id,u.name = 2,"cat"//改变u的值
    u.TestValue()//u为改变的值
    uValue()//该方法为复制值的方法
    /* out
    TestValue 0xc0000040a8,{1 Tom}
    TestValue 0xc0000040d8,{2 cat}
    TestValue 0xc000004108,{1 Tom}
     */
    fmt.Println("---------------------------------")
    //总结:方法中的对象为值的拷贝,还是地址的传递,与方法本身的声明相关
    //与调用方法传递的类型无关
    //由于*T的方法包含了*T+T的方法所以可以调用
    u1 := User{1,"Tom"}
    fmt.Printf("u1 %p,%v\n",&u1,u1)
    mv := User.TestValue
    mv(u1)//由于方法有一个隐藏的this指针
    //mv中的u1是对主函数中u1的值拷贝,地址并不相同

    mp := (* User).TestPointer
    mp(&u1)//mp中的u1与主函数中u1是同一个内存且地址相同

    mp2 := (* User).TestValue
    mp2(&u1)//mp2中的u1是对主函数中u1的值拷贝,地址并不相同


}

你可能感兴趣的:(方法集与表达式)