我需要一個鏈接節點來保存一些不同的介面型別,所以我用泛型做了它,但是泛型型別any不能與 nil 進行比較,它顯示錯誤,如注釋中所示:
package main
type myInterface interface {
}
type node[T any] struct {
next *node[T]
leaf T
}
func (n *node[T]) GetFirstNodeHasLeaf() *node[T] {
if n.leaf != nil { // <---- error here: cannot compare n.leaf != nil (mismatched types T and untyped nil)
return n
}
if n.next == nil {
return nil
} else {
return n.next.GetFirstNodeHasLeaf()
}
}
func main() {
var n = &node[myInterface]{}
// fill n with lots of nodes
n.GetFirstNodeHasLeaf() // get the first node that has (leaf != nil)
}
我還嘗試與默認值進行比較
var nilT T
if n.leaf != nilT { // <-- same problem
并將節點型別限制為
type node[T myInterface] struct {
同樣的錯誤,如何解決?謝謝。
uj5u.com熱心網友回復:
使用介面來實體化泛型型別node可能是一個概念缺陷。所以讓我們先看一般案例,最后看介面案例。
使用comparable和T
如果要使用等式運算子,例如==和!=型別引數型別的值,則約束必須是comparable.
type node[T comparable] struct {
next *node[T]
leaf T
}
但是您不會針對 進行測驗nil,而是針對T的零值進行測驗,這取決于您實體化它的方式,可能不是nil.
T在這種情況下,您將為其零值宣告一個型別的變數:
var zero T
if n.leaf != zero {
return n
}
但是介面型別不實作comparable.
使用any和*T
作為替代方案,您可以保留約束any并將該欄位宣告leaf為指向T. 這支持相等運算子,因為leaftype 不再是型別引數,它是一個指標:
type node[T any] struct {
next *node[T]
leaf *T
}
func (n *node[T]) GetFirstNodeHasLeaf() *node[T] {
if n.leaf != nil { // ok, leaf is a pointer type
return n
}
...
}
使用any和T
使用約束any,T不支持相等運算子,因為從技術上講,您可以node使用任何型別進行實體化,包括那些不可比較的型別。
因此,只要T受約束any并且該欄位不是指標,您就只能使用反射來檢查零值(nil對于指標型別):
if !reflect.ValueOf(n.leaf).IsZero() {
return n
}
T最后,考慮到如果是介面型別,上面的代碼不起作用。測驗的是界面中框出的動態值。如果T確實必須是介面,請使用以下命令測驗零值:
// leaf is an interface type
if !reflect.ValueOf(&n.leaf).Elem().IsZero() {
return n
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/511199.html
標籤:去仿制药
上一篇:HTTP協議有必要學習嗎?
