我需要一个链接 node 来保存一些不同的接口类型,所以我用泛型创建了它,但泛型类型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)
}

我还try 与缺省值进行比较

    var nilT T
    if n.leaf != nilT { // <-- same problem

并将 node 类型限制为

type node[T myInterface] struct {

同样的错误,如何解决这个问题?谢谢.

推荐答案

使用接口实例化像node这样的泛型类型可能是一个概念上的缺陷.那么让我们先来看看一般的用例,最后看看接口用例.

Using comparable and 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.

Using any and *T

或者,您可以保留约束any,并将字段leaf声明为指向T的指针.这支持相等运算符,因为leaf类型不再是类型参数,而是一个指针:

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
    }
...
}

Using any and T

使用约束any,T不支持相等运算符,因为从技术上讲,您可以使用任何类型实例化node,包括那些不可比较的类型.

因此,只要Tany约束,且该字段不是指针,则只能使用反射来判断零值(指针类型`为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
}

Go相关问答推荐

JWT库返回及时无效的令牌有效

"k8s.io/apimachinery/pkg/runtime.对象(缺少方法DeepCopyBody)

如何在定制普罗米修斯出口商中测试动态计量注册?

运行add. inf,这样我们就可以在app.conf中使用. inf参数了?

如何在jsonrpc服务器的服务器端捕获错误?

ChromeDriver不存在(高朗selenium)

Golang Docker Selenium Chrome

如何将字节文件高效地读入int64切片?

使用goqu无法获取响应

如何将 DirName 和 serial 添加到 X509v3 Authority Key Identifier

当图像是对象数组的元素时,如何显示存储为页面资源的图像?

Golang 中具体类型的错误片段

如何在模板中传递和访问 struct 片段和 struct

如何过滤来自 fsnotify 的重复系统消息

grpc-gateway:重定向与定义不匹配(原始文件)

如何在自定义验证函数中获取 struct 名称

Go 泛型:自引用接口约束

具有近似约束的函数值导致的实例化失败

防止在 Go 公用文件夹中列出目录

Gin中测试模式有什么用