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

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

使用泛型實現可比較的結構

使用泛型實現可比較的結構

Go
胡說叔叔 2022-11-08 15:13:30
考慮以下版本 go1.18beta2 linux/amd64 的代碼片段    type Vector[T comparable] struct {       data_ []T    }        func (v *Vector[T]) Contains(e T) bool {       for _, x := range v.data_ {          if x == e {             return true          }       }       return false    }        func TestVector(t *testing.T) {       v2 := Vector[Vector[int]]{}    }這不會編譯并給出錯誤:“Vector[int] does not implement comparable”僅僅是因為Vector沒有定義相等運算符。但是,我找不到如何定義它們。問題:這種創建可比較結構的方法是否不允許,為什么?還是文檔還沒有寫好?
查看完整描述

1 回答

?
一只斗牛犬

TA貢獻1784條經驗 獲得超2個贊

約束comparable由語言規范預先聲明和支持。您不能“手動”使類型實現它。該文檔在規范中可用(在Type Constraints下):


預先聲明的接口類型可比較表示所有可比較的具體(非接口)類型的集合。具體來說,類型 T 在以下情況下實現可比較:


T不是接口類型,T支持操作 == 和 !=; 或者

T是一個接口類型,并且類型T集中的每個類型都實現了可比性。

您的類型Vector[T comparable]不滿足任何這些條件。它不是接口類型,也不支持相等操作,因為它的一個字段data_ []T由于是切片而無法比較——即使元素類型受comparable.


約束的目的comparable實際上只是允許使用==和!=運算符編寫通用代碼。如果一個類型在設計上是不可比較的,那么你就不能編寫這樣的代碼。即使Vector沒有類型參數也是如此。


如果您的目標是實例化Vector[Vector[T]]并允許在 的實例之間進行相等性測試Vector[T],您可能需要添加一個Equal處理此特定用例的方法——只允許使用與接收器相同的類型參數實例化的向量:


func (v *Vector[T]) Equal(e Vector[T]) bool {

    // test equality in a way that makes sense for this type

}

值得一提的是,有一種方法可以自行Vector[T comparable]比較,data_即將字段更改為指向切片的指針:


type Vector[T comparable] struct {

    data_ *[]T

}

Vector[Vector[int]]現在用編譯實例化。然而,除了用結構字面量(操場)進行初始化非常麻煩之外,它還帶有指針比較的所有警告。進一步來說:


如果兩個指針值指向同一個變量,或者兩者的值都為零,則它們的值相等。指向不同的零大小變量的指針可能相等,也可能不相等。


現在比較測試和字段中x == e存儲的內存地址是否相同。這可能會扭曲比較兩個實例的語義——如果兩個向量實例持有對同一切片的引用,那么說它們相等是否正確?也許。這取決于您的程序想要做出的假設。就個人而言,我認為這實際上并不比使用單獨的方法和/或重新設計數據類型更好,但像往常一樣,YMMV。data_xeVector[T]Equal


另請注意,如果您實例化為Vector[float64]并比較NaN值,則比較將是錯誤的。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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