深入研究類型別名的複雜性
考慮以下程式碼片段:
package main import ( "fmt" "time" ) type dur struct { time.Duration } type durWithMethods dur type durWithoutMethods time.Duration func main() { var d durWithMethods // works ?? fmt.Println(d.String()) var dWM durWithoutMethods fmt.Println(dWM.String()) // doesn't compile }
人們可能會思考以下程式碼片段:
人們可能會思考為什麼直接time.Duration (durWithoutMethods) 的別名不繼承任何方法,而嵌套的型別別名(durWithMethods) 授予對它們的存取權限。這種混淆源於類型定義和類型別名之間的根本區別。
定義新型別與重新命名現有型別
在 Go 中,型別宣告分為兩類:型別定義與型別別名。類型定義透過嵌入一個或多個現有類型來誕生新類型。它們僅從頂層嵌入類型繼承方法,而不是從巢狀類型繼承。另一方面,類型別名只是將新識別碼綁定到現有類型的簡寫。它們不會建立新類型,因此基礎類型保持不變。與基礎類型關聯的任何方法仍然可以透過原始名稱或別名輕鬆存取。
理解 durWithMethods
類型 durWithMethods 有效地擴展了 dur 類型嵌入它。由於dur嵌入了time.Duration,因此它繼承了Duration的方法,包括String()。因此,程式碼中的 d.String() 按預期工作。
揭開 durWithoutMethods
與 durWithMethods 不同,durWithoutMethods 是 time.Duration 的直接別名。它不擴展任何內容,因此它僅由原始 time.Duration 類型組成。 time.Duration 的方法不會轉移到 durWithoutMethods,因為它是一個獨特的類型,具有自己單獨的一組方法。因此,dWM.String() 將無法編譯。以上是為什麼 Go 中的型別別名從嵌入型別繼承時表現不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!