Golang 表達(dá)式 :根據(jù)調(diào)用者不同片效,方法分為兩種表現(xiàn)形式:
instance.method(args...) ---> <type>.func(instance, args...)
前者稱為 method value芒帕,后者 method expression虱疏。
兩者都可像普通函數(shù)那樣賦值和傳參毒涧,區(qū)別在于 method value 綁定實(shí)例力试,而 method expression 則須顯式傳參徙邻。
package main
import "fmt"
type User struct {
id int
name string
}
type Manager struct {
User//通過組合實(shí)現(xiàn)繼承
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為當(dāng)前u的方法,復(fù)制了u的值
u.id,u.name = 2,"cat"http://改變u的值
u.TestValue()//u為改變的值
uValue()//該方法為復(fù)制值的方法
/* out
TestValue 0xc0000040a8,{1 Tom}
TestValue 0xc0000040d8,{2 cat}
TestValue 0xc000004108,{1 Tom}
*/
fmt.Println("---------------------------------")
//總結(jié):方法中的對象為值的拷貝畸裳,還是地址的傳遞缰犁,與方法本身的聲明相關(guān)
//與調(diào)用方法傳遞的類型無關(guān)
//由于*T的方法包含了*T+T的方法所以可以調(diào)用
u1 := User{1,"Tom"}
fmt.Printf("u1 %p,%v\n",&u1,u1)
mv := User.TestValue
mv(u1)//由于方法有一個(gè)隱藏的this指針
//mv中的u1是對主函數(shù)中u1的值拷貝,地址并不相同
mp := (* User).TestPointer
mp(&u1)//mp中的u1與主函數(shù)中u1是同一個(gè)內(nèi)存且地址相同
mp2 := (* User).TestValue
mp2(&u1)//mp2中的u1是對主函數(shù)中u1的值拷貝怖糊,地址并不相同
}