考慮以下版本 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沒有定義相等運算子。但是,我找不到如何定義它們。
問題:這種創建可比較結構的方法是否不允許,為什么?還是檔案還沒有寫好?
uj5u.com熱心網友回復:
約束comparable由語言規范預先宣告和支持。您不能“手動”使型別實作它。該檔案在規范的尖端版本中可用(在Type Constraints下):
預先宣告的介面型別可比較表示所有可比較的具體(非介面)型別的集合。具體來說,型別 T 在以下情況下實作可比較:
T不是介面型別,T支持操作 == 和 !=; 或者T是一個介面型別,并且型別T集中的每個型別都實作了可比性。
您的型別Vector[T comparable]不滿足任何這些條件。它不是介面型別,并且不支持相等操作。這來自于上面參考中鏈接的比較運算子的規范,無論型別引數如何:
如果結構值的所有欄位都是可比較的,則結構值是可比較的。如果它們對應的非空白欄位相等,則兩個結構值相等。
[...]
Slice、 map 和 function 值不可比較
并且 field data_ []T, even if Tis constrained bycomparable是不可比較的,因為它是一個切片型別,并且切片型別是不可比較的。
約束的目的comparable實際上只是允許使用==和!=運算子撰寫通用代碼。如果一個型別在設計上是不可比較的,那么你就不能撰寫這樣的代碼。即使Vector沒有型別引數也是如此。
如果您的目標是允許 的實體之間進行相等性測驗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
}
Now instantiation with Vector[Vector[int]] compiles. However, beside being very cumbersome to initialize with struct literals (playground), it comes with all caveats of pointer comparison. More specifically:
Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
Now the comparison x == e tests that the memory address stored in the data_ field in x and e is the same. This might skew the semantics of comparing two Vector[T] instances — is it correct to say that two vector instances are equal if they hold a reference to the same slice? Maybe. It depends on the assumptions your program wants to make. Personally, I don't think this is actually better than having a separate Equal method and/or redesigning your data types, but as usual, YMMV.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426098.html
