我正在編寫一些數據結構來讓我的腳弄濕并學習 Go 語言,并且正在為 Go 缺乏泛型而苦苦掙扎。在我的實現中,我選擇強制每個用戶實現一個接口,以便我的結構可以抽象地引用這些對象,但我不喜歡我的解決方案,因為正如您將看到的那樣,這在編譯時沒有得到驗證。比較器接口保存在容器中的每個對象都必須實現Compare以下簽名的函數(如果您只想保存原始類型,則很麻煩)type Comparer interface { Compare(Comparer) int}然后,您可以擁有實現接口的各種元素,例如float64或自定義結構:浮動64type number float64func (n1 number) Compare(comparer Comparer) int { n2, _ := comparer.(number) if n1 > n2 { return 1 } else if n1 < n2 { return -1 } else { return 0 }}人type Person struct { Age int}func (p1 Person) Compare(comparer Comparer) int { p2, _ := comparer.(Person) if p1.Age > p2.Age { return 1 } else if p1.Age < p2.Age { return -1 } else { return 0 }}現在我可以比較其中的一些東西:func main() { fmt.Println(number(2).Compare(number(4))) // -1 fmt.Println(Person{26}.Compare(Person{28})) // -1 fmt.Println(Person{26}.Compare(number(28))) // 1}這里的問題是我不應該比較 aPerson和 a number。我意識到我可以在運行時檢查類型,但我想找到 a) 一種驗證類型的編譯時方法或 b) 一種不同的方法來通用地實現數據結構。問題我知道使用內置數據結構幾乎可以做任何可能需要的事情……但是如果沒有泛型或運行時類型檢查,人們如何制作自己的數據結構呢?由于 Go 中的接口實現似乎使用了鴨子類型,那么 Go 在編譯時如何強制類型?
1 回答

白板的微信
TA貢獻1883條經驗 獲得超3個贊
我的意思是該代碼沒有任何不安全的地方......只是沒有編譯時安全。例如,在您下面的方法中,第一行對 進行類型斷言comparer,如果它不是數字并且您沒有_LHS 上的第二項,那么它將返回一個錯誤,您可以采取相應的行動?;蛘吣憧梢栽跊]有它的情況下調用它,并且panic會發生將它留給調用者來處理它(這很合適,因為他們是用錯誤的參數調用方法的人,就像InvalidOperationException在 C# 中得到一個一樣)。
func (n1 number) Compare(comparer Comparer) int {
n2, _ := comparer.(number)
if n1 > n2 {
return 1
} else if n1 < n2 {
return -1
} else {
return 0
}
}
這與像 C# 這樣的語言之間的區別純粹在于泛型,它允許您以更高的編譯時安全性來執行這些類型的事情(因為您不能錯誤地調用該方法)。話雖如此,在 C# 有泛型之前有一段時間,而在此之前的許多語言根本沒有它們。即使在具有泛型的語言中,這些操作也不會比您經常進行的轉換更不安全。
- 1 回答
- 0 關注
- 201 瀏覽
添加回答
舉報
0/150
提交
取消