X 沒有實作 Y(...方法有指標接收器)
php小編小新將在這篇文章中探討一個關於X未能實現Y的問題。在這個問題中,我們使用了一個指標接收器的方法。透過這個方法,我們可以更好地理解為什麼X無法實現Y,並且找到解決這個問題的方法。在接下來的內容中,我們將詳細討論這個問題,並提供一些解決方案。
問題內容
已經有幾個關於「X 沒有實作Y(...方法有指標接收器)」問題的問答,但對我來說,他們似乎在談論不同的事情,並且不適用於我的具體情況。
因此,我沒有將問題變得非常具體,而是將其變得廣泛和抽象 - 似乎有幾種不同的情況可能會導致此錯誤發生,有人可以總結一下嗎?
即如何避免該問題,如果發生,有哪些可能性?謝謝。
解決方法
當您嘗試將具體類型指派或傳遞(或轉換)為介面類型時,會出現此編譯時錯誤;並且類型本身並不實作該接口,僅實作一個指向該類型的指標。
簡短摘要:對變數的賦值如果所指派的值實作了所指派的接口,則介面類型有效。如果它的方法集是介面的超集,它就會實現它。指標類型的方法集包括具有指標和非指標接收器的方法。非指標類型的方法集僅包括具有非指標接收器的方法。
讓我們來看一個例子:
type stringer interface { string() string } type mytype struct { value string } func (m *mytype) string() string { return m.value }
stringer
介面類型只有一個方法:string()
。儲存在介面值 stringer
中的任何值都必須具有此方法。我們也建立了一個 mytype
,並建立了一個有指標接收器的方法 mytype.string()
。這表示 string()
方法位於 *mytype
類型的 方法集 中,但不在 mytype
中。
當我們嘗試將 mytype
的值指派給 stringer
類型的變數時,我們收到以下錯誤:
m := mytype{value: "something"} var s stringer s = m // cannot use m (type mytype) as type stringer in assignment: // mytype does not implement stringer (string method has pointer receiver)
但如果我們嘗試將 *mytype
類型的值指派給 stringer
,則一切正常:
s = &m fmt.println(s)
我們得到了預期的結果(在 go playground 上嘗試):
something
因此獲得此編譯時錯誤的要求:
- 被指派(或傳遞或轉換)的非指標具體類型的值
- 被指派(或傳遞或轉換)的介面類型
- 具體類型具有介面所需的方法,但具有指標接收器
解決問題的可能性:
- #必須使用指向值的指針,其方法集將包括帶有指針接收者的方法
- 或接收者類型必須變更為非指標,因此非指標特定類型的方法集也將包含該方法(從而滿足介面)。這可能可行,也可能不可行,就好像該方法必須修改值一樣,非指標接收器不是選項。
結構與嵌入
當使用結構和嵌入時,通常不是「你」實作介面(提供方法實作),而是嵌入 struct
中的類型。就像這個例子:
type mytype2 struct { mytype } m := mytype{value: "something"} m2 := mytype2{mytype: m} var s stringer s = m2 // compile-time error again
再次編譯時出錯,因為mytype2
的方法集不包含內嵌mytype
的string()
方法,只有*mytype2
的方法集,所以下面的方法有效(在去遊樂場):
var s stringer s = &m2
如果我們嵌入*mytype
並且只使用非指標 mytype2
,我們也可以使其工作(在去遊樂場 ):
type mytype2 struct { *mytype } m := mytype{value: "something"} m2 := mytype2{mytype: &m} var s stringer s = m2
此外,無論我們嵌入什麼(mytype
或*mytype
),如果我們使用指標*mytype2
,它總是可以工作(在去遊樂場):
type mytype2 struct { *mytype } m := mytype{value: "something"} m2 := mytype2{mytype: &m} var s stringer s = &m2
規範中的相關部分(來自結構類型部分):
给定一个结构体类型 s
和一个名为 t
的类型,提升的方法包含在该结构体的方法集中,如下所示:
- 如果
s
包含匿名字段t
,则s
和*s
的方法集均包含接收者为t
的提升方法。*s
的方法集还包括接收者*t
的提升方法。 - 如果
s
包含匿名字段*t
,则s
和*s
的方法集都包含接收者为t
或*t
的提升方法。
换句话说:如果我们嵌入一个非指针类型,非指针嵌入器的方法集只能获取具有非指针接收器的方法(来自嵌入类型)。
如果我们嵌入一个指针类型,非指针嵌入器的方法集将获取具有指针和非指针接收器的方法(来自嵌入类型)。
如果我们使用指向嵌入器的指针值,则无论嵌入类型是否是指针,指向嵌入器的指针的方法集始终都会获取具有指针和非指针接收器的方法(从嵌入类型)。
注意:
有一个非常相似的情况,即当您有一个包含 mytype
值的接口值时,并且您尝试 类型断言 另一个接口值,stringer
。在这种情况下,由于上述原因,断言将不成立,但我们会得到一个略有不同的运行时错误:
m := mytype{value: "something"} var i interface{} = m fmt.println(i.(stringer))
运行时恐慌(在 go playground 上尝试一下):
panic: interface conversion: main.mytype is not main.stringer: missing method string
尝试转换而不是类型断言,我们得到了我们正在讨论的编译时错误:
m := MyType{value: "something"} fmt.Println(Stringer(m))
以上是X 沒有實作 Y(...方法有指標接收器)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

OpenSSL,作為廣泛應用於安全通信的開源庫,提供了加密算法、密鑰和證書管理等功能。然而,其歷史版本中存在一些已知安全漏洞,其中一些危害極大。本文將重點介紹Debian系統中OpenSSL的常見漏洞及應對措施。 DebianOpenSSL已知漏洞:OpenSSL曾出現過多個嚴重漏洞,例如:心臟出血漏洞(CVE-2014-0160):該漏洞影響OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻擊者可利用此漏洞未經授權讀取服務器上的敏感信息,包括加密密鑰等。

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

後端學習路徑:從前端轉型到後端的探索之旅作為一名從前端開發轉型的後端初學者,你已經有了nodejs的基礎,...

本文討論了通過go.mod,涵蓋規範,更新和衝突解決方案管理GO模塊依賴關係。它強調了最佳實踐,例如語義版本控制和定期更新。

本文介紹在Debian系統下監控PostgreSQL數據庫的多種方法和工具,助您全面掌握數據庫性能監控。一、利用PostgreSQL內置監控視圖PostgreSQL自身提供多個視圖用於監控數據庫活動:pg_stat_activity:實時展現數據庫活動,包括連接、查詢和事務等信息。 pg_stat_replication:監控複製狀態,尤其適用於流複製集群。 pg_stat_database:提供數據庫統計信息,例如數據庫大小、事務提交/回滾次數等關鍵指標。二、借助日誌分析工具pgBadg
