我试图在Go中定义一个通用函数,它接受具有特定字段的值,例如ID int.我try 过几种方法,但似乎都不管用.下面是我try 过的一个例子.

package main

import (
    "fmt"
)

func Print[T IDer](s T) {
    fmt.Print(s.ID)
}

func main() {
    Print(Person{3, "Test"})
}

type IDer interface {
    ~struct{ ID int }
}

type Person struct {
    ID   int
    Name string
}

type Store struct {
    ID     int
    Domain string
}

这里是playground 链接:https://gotipplay.golang.org/p/2I4RsUCwagF

在上面的例子中,我想保证传递给Print函数的每个值都有一个属性ID int,该属性也可以在函数中访问.有没有什么方法可以实现这一点,而不用在接口(例如GetID() int)中定义方法?

推荐答案

我有没有办法不用在接口中定义方法(例如GetID()int)就能实现这一点?

不,必须在接口中定义方法.

Go 1.18中的泛型实现不支持 struct 类型,尽管最初的类型参数建议会这样做.要访问联合中的公共字段,另请参见this explanation.

尽管如此,我认为值得指出一个容易从你的例子中产生的误解:近似值~T(tilde类型)的意思是"基本类型为T的一组类型".

现在,当你写作时:

~struct{ ID int }

这意味着其基础类型为exactly struct{ ID int }的类型.不管怎样,这不包括包含字段ID int and或其他内容的 struct .例如,type Foo struct { ID int; Name string }的基本类型是struct { ID int; Name string },而不是struct{ ID int },因此无论如何都不能满足约束.

当前时间参数实现没有指定部分 struct 类型的语法.我回忆起在接口约束中添加字段术语(以及类型术语和方法)的proposal,行中有一些内容:

type IDer interface {
    ID int
}

这将在不 destruct tilde ~含义的情况下实现您正在try 的操作.但这不会包含在Go 1.18中.

Go相关问答推荐

golang 的条件储存库

如何在AWS SDK Go v2 STS上正确使用重试

可以';t从主机连接到ScyllaDB容器

将这两个函数合二为一的惯用方法

生成一个 CSV/Excel,在 Golang 中该列的下拉选项中指定值

Go - 永远停止带有上下文的循环

GORM中是否可能自动迁移具有循环关系的表?

Gorm 在自定义字符串类型上返回 scanner 错误

也许在 golang 中包(字符串和字符串类型不匹配)

go version -m 输出中的箭头符号=>是什么意思?

go-echo中如何防止+转义

Golang并发写入多个文件

Golang Getrlimit 返回与 ulimit 不同的值

如何在 golang 中同时加载 .env 文件和 os 环境变量

为什么 0 big.Int 的 .Bytes() 值是空切片?

使用 oklog/run 来自 Go 编译器的错误(无值)用作值

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

如何使用带有Electron 表格 ID、Electron 表格名称、表格 ID 和值的 golang 在 googlesheet 中插入数据

函数参数的判断顺序是什么?

如果在调用 http.Get(url) 时发生错误,我们是否需要关闭响应对象?