在Golang中,如何将泛型类型的接口与nil进行比较?

2023-12-28

我需要一个链接节点来保存一些不同的接口类型,所以我用泛型来制作它,但是泛型类型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 {

同样的错误,请问如何解决?谢谢。


使用接口实例化泛型类型,例如node可能是一个概念缺陷。因此,让我们先看一般情况,最后看接口情况。

Using comparable and T

如果你想使用等号运算符== and !=对于类型参数类型的值,约束必须是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。这支持相等运算符,因为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
    }
...
}

Using any and T

随着约束any, T不支持相等运算符;你可以实例化node几乎任何类型,包括那些不可比较的类型。

只要该字段不是指针,就只能使用反射来检查零值(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
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Golang中,如何将泛型类型的接口与nil进行比较? 的相关文章

  • 如何分析 VSCode 中函数的性能

    我用 C Golang 编写了一个程序 如何找到占用最高 CPU 周期的函数 目的是提高正在执行的程序的性能 2021 年 10 月 金香儿哈娜 https github com hyangah宣布 tweet https twitter
  • 继承的静态成员的静态初始化

    考虑这个示例代码 public class A
  • 无界通配符类型在运行时如何工作?

    我知道无界通配符类型将被删除并替换为对象 vy 类型擦除 无界通配符类型是可具体化类型 其类型信息在运行时完全可用 我知道两者之间的区别List List List list new ArrayList
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • Map:为 Integer 和 Double 类型定义方法,但不为 String 类型定义方法

    我正在尝试定义一个方法putIfGreaterThan 为了我的新Map class 给定一个键 仅当新值大于旧值时 它才会用新值替换旧值 我知道我可以通过组合来实现这一点 通过有一个private final Map
  • 展平嵌套结构会导致切片的切片

    所以我有一个像这样的结构 type Bus struct Number string Name string DirectStations Station Station is another struct ReverseStations
  • 我怎么知道我的所有 goroutine 确实正在使用 golang 的同步包等待一个条件

    我有一个应用程序 我正在创建多个 goroutine 来同时执行某个任务 所有工作协程都会等待条件 事件发生 一旦事件被触发 它们就会开始执行 创建完所有goroutines后 主线程在发送广播信号之前应该知道所有goroutines确实处
  • 如何将UTC时间转换为unix时间戳

    我正在寻找将 UTC 时间字符串转换为 unix 时间戳的选项 我的字符串变量是02 28 2016 10 03 46 PM并且需要将其转换为 unix 时间戳 例如1456693426 知道该怎么做吗 首先 unix时间戳14566934
  • Golang 正则表达式命名组和子匹配

    我正在尝试匹配正则表达式并获取匹配的捕获组名称 当正则表达式仅与字符串匹配一次时 这是有效的 但如果它与字符串匹配多次 SubexpNames不返回重复的名称 这是一个例子 package main import fmt regexp fu
  • GoLang ssh:尽管将其设置为 nil,但仍出现“必须指定 HosKeyCallback”错误

    我正在尝试使用 GoLang 连接到远程服务器 在客户端配置中 除了用户和密码之外 我将 HostKeyCallback 设置为 nil 以便它接受每个主机 config ssh ClientConfig User user HostKey
  • 受约束泛型类型参数的继承

    我知道不可能从泛型类型参数继承 但是在为抽象类型的派生类实现通用代理时会很方便 有谁知道为什么这是不可能的 C 示例 abstract class Foo public virtual void Bar nop class FooProxy
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • 如何在golang中解析JSON而不需要解组两次

    我有一个 Web 套接字连接 它在 JSON 对象中发送不同类型的消息 并且我想将内容解组到一些已知的结构中 为此 我认为我应该执行以下操作 步骤 1 将 JSON 解组为通用映射 字符串 接口 步骤 2 找到我要找的钥匙 步骤 3 尝试将
  • “go.tools”的权限被拒绝错误

    当我尝试安装 go 工具时 我的权限被拒绝 usr local go pkg tool linux amd64 cover 我可以接受 因为它是 usr local 目录及需求root使用权 但我的第一个疑问是为什么当我设置时它试图安装在这
  • Weld 中的 JavaEE CDI:通用事件?

    我有一个基于泛型的特定事件处理的想法 但似乎 Weld 无法处理它们 我询问了 google 但找不到替代的 CDI 扩展 Question 是否有 CDI 扩展可以处理通用类型事件的事件传播 下面是我遇到的明确问题 我有三个常规事件 En
  • 将 time.Time 转换为字符串

    我正在尝试将数据库中的一些值添加到 string在围棋中 其中一些是时间戳 我收到错误 无法在数组元素中使用 U Created date 类型 time Time 作为类型字符串 我可以转换吗time Time to string typ
  • Golang 正则表达式在字符串之间替换

    我有一些可能采用以下形式的字符串 MYSTRING MYSTRING n MYSTRING n MYSTRING randomstringwithvariablelength n 我希望能够将其正则表达式为MYSTRING foo 基本上替
  • Java中未绑定通配符泛型的用途和要点是什么?

    我不明白未绑定通配符泛型有什么用 具有上限的绑定通配符泛型 stuff for Object item stuff System out println item Since PrintStream println 可以处理所有引用类型 通
  • 如何关闭 gorm 1.20.0 中的数据库实例

    由于我没有在 Close 函数中找到 gorm 实例 任何帮助将不胜感激 dbURI fmt Sprintf user s password s dbname s port s sslmode s TimeZone s username p
  • 在 Visual Studio Code 中调试 Go 测试

    在我的 Windows 计算机上 我安装了 Visual Studio Code 要手动运行测试 我进入控制台到项目文件夹并输入 go test main test go 它工作完美 但我遇到一种情况 我需要调试我的测试以了解发生了什么 为

随机推荐