2 回答

TA貢獻1848條經驗 獲得超2個贊
func?test(v?*Visitor)??{ ????v.work()?//?error ????}
v.work()
應該是一個方法調用。但是v
是 type?*Visitor
,一個指向接口的指針。指向接口的指針有 0 個方法,它不實現任何東西(空接口除外interface{}
)。
使用非指針時,值v
(或更確切地說它的類型)有一個 method?work()
,因此您可以調用它:
func?test(v?Visitor)??{ ????v.work()?//?ok ????}
這里v.work()
有效,因為v
is 是一個接口類型Visitor
,它包含方法work()
。
可能令人困惑的是,如果您將方法添加到(非指針,非接口)具體類型,則相應的指針類型也將具有該方法,您可以調用它。這是在規范中:方法集:
一個類型可能有一個與之關聯的方法集。接口類型的方法集就是它的接口。任何其他類型的方法集
T
由所有用接收者類型聲明的方法T
組成。對應指針類型的方法集是所有用receiver?or聲明的方法的集合(即也包含了 的方法集)。?*T
*T
T
T
進一步的規則適用于包含嵌入式字段的結構,如結構類型部分所述。任何其他類型都有一個空方法集。在一個方法集中,每個方法必須有一個唯一的非空白?方法名稱。
不同之處在于您對接口類型進行了相同的嘗試,但這是行不通的。它適用于具體(非接口)類型。教訓是永遠不要使用指向接口的指針,除非你能解釋為什么需要它(很少需要)。

TA貢獻1887條經驗 獲得超5個贊
正如錯誤明確指出的那樣:
v.work 未定義(類型 *Visitor 是指向接口的指針,而不是接口)
這是因為 work() 函數是在指向接收器的指針上調用但在值上定義的。
type?Visitor?interface?{ ????work() }
但是在第二種情況下你正在傳遞指針類型的接收器,你會得到一個錯誤。
在 Golang 規范中,方法集定義為:
一個類型可能有一個與之關聯的方法集。接口類型的方法集就是它的接口。任何其他類型T的方法集由所有聲明為接收者類型T的方法組成。對應指針類型*T的方法集是所有聲明為接收者*T或T的方法的集合(即還包含方法T 組)。進一步的規則適用于包含嵌入字段的結構,如結構類型部分所述。任何其他類型都有一個空方法集。在一個方法集中,每個方法必須有一個唯一的非空方法名。
您可以采用的一種方法是使用可以在其上調用方法 work() 的結構來實現接口。
package main
import "fmt"
type Visitor struct{}
type Visit interface {
? ? work()
}
func test(v Visit)? {
? ? v.work() // error
? ? fmt.Printf("%+v", v)
}
func (v *Visitor) work(){}
func main(){
? ? ? ?v := Visitor{}
? ? ? ?test(&v)
}
- 2 回答
- 0 關注
- 157 瀏覽
添加回答
舉報