亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么指針類型可以訪問嵌入類型的所有方法

為什么指針類型可以訪問嵌入類型的所有方法

Go
qq_花開花謝_0 2022-07-11 16:24:42
下面是嘗試embed類型的源碼。修改函數定義為func (f *F) Modify(f2 F)。誰能解釋為什么第一個反射循環中沒有顯示修改函數?但是在第二個反射循環中,Modify和Validate都可以從 *s 中得到。package mainimport "fmt"import "reflect"type F func(int) boolfunc (f F) Validate(n int) bool {    return f(n)}func (f *F) Modify(f2 F) {    *f = f2}type B boolfunc (b B) IsTrue() bool {    return bool(b)}func (pb *B) Invert() {    *pb = !*pb}type I interface {    Load()    Save()}func PrintTypeMethods(t reflect.Type) {    fmt.Println(t, "has", t.NumMethod(), "methods:")    for i := 0; i < t.NumMethod(); i++ {        fmt.Print(" method#", i, ": ",                t.Method(i).Name, "\n")    }}func main() {    var s struct {        F        *B        I    }    PrintTypeMethods(reflect.TypeOf(s))    fmt.Println()    PrintTypeMethods(reflect.TypeOf(&s))}輸出:struct { main.F; *main.B; main.I } has 5 methods: method#0: Invert method#1: IsTrue method#2: Load method#3: Save method#4: Validate*struct { main.F; *main.B; main.I } has 6 methods: method#0: Invert method#1: IsTrue method#2: Load method#3: Modify method#4: Save method#5: Validate
查看完整描述

2 回答

?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

Method sets

一個類型可能有一個與之關聯的方法集。接口類型的方法集就是它的接口。任何其他類型 T 的方法集由所有用接收器類型 T 聲明的方法組成。對應指針類型 *T 的方法集是用接收器 *T 或 T 聲明的所有方法的集合(即它還包含該方法T 組)。進一步的規則適用于包含嵌入字段的結構,如結構類型部分所述。任何其他類型都有一個空方法集。在方法集中,每個方法必須有一個唯一的非空方法名稱。

Struct types

如果 xf 是表示該字段或方法 f 的合法選擇器,則稱為提升結構 x 中嵌入字段的 字段或方法 f。

...

給定一個結構類型 S 和一個定義類型 T,提升的方法包含在結構的方法集中,如下所示:

  • If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.

  • 如果 S 包含嵌入字段 *T,則 S 和 *S 的方法集都包含帶有接收器 T 或 *T 的提升方法。


查看完整回答
反對 回復 2022-07-11
?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

如果m為類型定義了方法T,則該方法對T和都可用*T:


type T struct {}


func (t T) m() {}


func main() {

   t:=T{}

   tp:=&T{}

   t.m()   // valid: m defined for T

   tp.m()  // valid: m defined for *T

}


如果一個方法是用指針接收器定義的,它只被定義為*T而不是為T':


func (t *T) n() {}


func main() {

   t:=T{}

   tp:=&TP{

   t.n() // Valid: &t is passed to n

   tp.b  // valid


   mp:=map[int]T{1:t}

   mp[1].n() // not valid. mp[1] is not addressable

   pp:=map[int]*T{1:&t}

   pp[1].n() // valid: pp[1] is *T

}

這樣做的原因很簡單:它可以防止無意中修改副本而不是縮進對象。如果帶有指針接收器的方法也可用于值類型,則使用以下代碼:


mp[1].n()

n,采用指針接收器,將修改 的值的副本mp[1],而不是存儲在 的值mp[1]。具有指針接收器的方法不可用于值類型的事實阻止了這一點,這將成為編譯錯誤,因為n沒有為 定義T,并且mp[1]不可尋址,從而阻止了編譯器將值轉換為指針。


查看完整回答
反對 回復 2022-07-11
  • 2 回答
  • 0 關注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號