在 Go 泛型中,如何对联合约束中的类型使用通用方法?

2024-04-17

我试图了解 Go 泛型(v1.18)中类型联合约束的用法。这是我尝试过的代码:

type A struct {
}

type B struct {
}

type AB interface {
    *A | *B
}

func (a *A) some() bool {
    return true
}

func (b *B) some() bool {
    return false
}

func some[T AB](x T) bool {
    return x.some()   // <- error
}

编译器抱怨:

x.some未定义(类型T没有字段或方法一些)

这是为什么?如果我不能使用类型的共享方法*A and *B,定义类型联合有什么意义*A | *B at all?

(显然,我可以使用共享方法定义一个接口并直接使用它。但在我的特定用例中,我想明确限制为某些类型。)


将方法添加到接口约束中,而不放弃泛型:

type AB interface {
    *A | *B
    some() bool
}

func some[T AB](x T) bool {
    return x.some()   // works
}

这限制了T到类型*A or *B并声明some() bool method.

然而,正如您已经发现的,这是一种解决方法。你是对的,它应该单独与类型联合一起使用。这是 Go 1.18 的限制。令人困惑的部分是语言规范似乎仍然支持你的理论(方法集 https://tip.golang.org/ref/spec#Method_sets):

接口类型的方法集是接口类型集中每个类型的方法集的交集(结果方法集通常只是接口中声明的方法集)。

此限制似乎仅记录在Go 1.18 发行说明 https://tip.golang.org/doc/go1.18:

当前的泛型实现具有以下限制:

[...] Go编译器目前只支持调用方法m在一个值上xof 类型 参数类型P if m明确声明为P的约束接口。 [...] 虽然m可能在方法集中P由于所有类型都在P实施m。我们希望在 Go 1.19 中取消这个限制。

Go跟踪器中的相关问题是#51183 https://github.com/golang/go/issues/51183, with 格里塞默的确认 https://github.com/golang/go/issues/51183#issuecomment-1049181719以及决定保留语言规范并记录限制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Go 泛型中,如何对联合约束中的类型使用通用方法? 的相关文章

随机推荐

  • g++:在涉及多个翻译单元的情况下 RVO 如何工作

    首先请看下面的代码 它由2个翻译单元组成 foo h class Foo public Foo Foo const Foo rhs void print const private std string str Foo getFoo foo
  • Spyder 绘制 Tkinter 后端无响应的图

    在spyder 4 以及使用3降级后 下绘图不起作用 我只是在做 data 1 2 3 plt plot data The output is a non responding frame After forcing to close it
  • 如何等到File.Exists?

    我有一个应用程序 正在侦听所选文件夹中的 log 文件 我用了FileSystemWatcher 但有一个问题 负责制作该文件的另一个应用程序采取以下步骤 制作一个 gz 文件 解压到txt文件 一些随机文件名 将 txt 名称更改为带有
  • 如何让客户端下载动态生成的非常大的文件

    我有一个导出功能 可以读取整个数据库并创建一个包含所有记录的 xls 文件 然后文件被发送到客户端 当然 导出完整数据库的时间需要大量时间 并且请求很快就会以超时错误结束 处理这种情况的最佳解决方案是什么 例如 我听说过使用 Redis 创
  • JavaScript 中是否可以从子类导入父模块?

    我有两个带有自己模块的文件 Sub js and 父 js 父 js import Sub from Sub js export default class Parent static createSomething new Sub Sub
  • 保存和读取 Integer Firestore Android

    我正在尝试为我的 Android 游戏创建一个简单的统计活动 我正在使用新的 Firestore 数据库 我已经能够将文档保存到我的 Firestore 数据库中 其中包含总分数 最近分数 平均分数 总游戏数和高分 但是当我尝试从数据库读回
  • 用于下载文件的 S3 模块在 ansible 中不起作用

    这是为从 S3 存储桶 artefact test 下载文件而编写的 ansible 代码 name Download customization artifacts from S3 s3 bucket artefact test obje
  • R 中 foreach() 内的 try() 问题

    我正在尝试使用try 函数来处理并行 for 循环中发生的错误 results lt foreach i 1 2 errorhandling remove dopar res lt try myfun i TRUE with myfun l
  • clang:自定义属性在 AST 中不可见

    我按照官方手册中的描述在 clang 中实现了一个自定义属性 http clang llvm org docs InternalsManual html how to add an attribute http clang llvm org
  • VBA代码导入

    我有一个用 excel 做的 VBA 项目 我将有许多工作簿将使用相同的代码 并且如果我进行更改 我不想将代码复制到所有工作簿 是否有办法将代码放在一个中心位置 然后让所有工作簿访问该代码 是的 你有两个选择 1 将代码复制并粘贴到个人工作
  • 按钮触发单击事件两次

    似乎有时 但并非总是 我的按钮单击事件被触发两次 事实上 这种情况似乎有时会发生 但并非总是如此 这让我很困惑 这是我的按钮
  • 如何使用 PHP 获取表单身份验证票证的内容

    我需要在 PHP 中撤消以下 ASP Net 进程 以便可以获取票证中的用户名和到期日期 我已经解密了 3DES 加密 下面的步骤 3 但我不确定下一步需要做什么 解密得到的字符串是字节数组吗 我应该能够将其转换为ascii 吗 因为事实并
  • 如何访问symfony2全局帮助函数(服务)中的服务容器?

    这个问题一开始我不明白为什么我不能将变量传递给 symfony2 全局辅助函数 服务 但是感谢比我更聪明的人 我意识到我的错误是尝试在一个类中使用 security context 而该类没有没有注射所以 这是最终的结果 即有效的代码 我没
  • 最顶部和最底部的水平分隔线未显示在 ListView 中

    我正在使用列表视图 但最顶部和最底部的水平条不显示 为什么 我正在使用这个 android divider android drawable divider horizontal bright 添加虚拟页脚和页眉 listViewConta
  • 按月分组的 SQL 结果

    我正在尝试返回滚动 12 个月期间的一些结果 例如 MONTH IN OUT January 210 191 February 200 111 March 132 141 April 112 141 May 191 188 etc 如何将结
  • 在 Go 模板中使用包含内部范围 (helm)

    我有一个模板 可以使用以下命令渲染多次range迭代 我可以访问变量外部变量 例如 Release Name没有问题 但是 当我包含模板时 我无法让它工作 range key val Values resources annotations
  • jQuery 每个都返回 [object Object]

    我的问题是 html 变量返回如下所示的内容 object Object object Object object Object object Object object Object 而不是元素 我应该做什么不同的事情 var html
  • SwiftMailer 不发送邮件,为什么?

    SwiftMail 不发送我的电子邮件 而mail 确实有效 与 一样here https stackoverflow com questions 3552937 swiftmailer wont send mail but mail wi
  • mongodb,复制和错误:{“$err”:“不是master和slaveOk = false”,“code”:13435}

    我第一次尝试 mongo 副本集 我在 ec2 上使用 ubuntu 并启动了三个实例 我使用了每个实例的私有 IP 地址 我选择作为主要的 下面是代码 mongo host Private IP Address rs initiate r
  • 在 Go 泛型中,如何对联合约束中的类型使用通用方法?

    我试图了解 Go 泛型 v1 18 中类型联合约束的用法 这是我尝试过的代码 type A struct type B struct type AB interface A B func a A some bool return true