【问题标题】:How to create a generic struct? [duplicate]如何创建通用结构?
【发布时间】:2021-09-05 12:54:49
【问题描述】:

如何构造通用结构?

我试过了:

type SafeSet[type T] struct {
    Values map[T]bool
}

我希望能够做到例如

SafeSet{ Values: make(map[net.Conn]bool) }
SafeSet{ Values: make(map[string]  bool) }
SafeSet{ Values: make(map[int]     bool) }

【问题讨论】:

  • 现在,使用 Go 1.17 及更早版本您不能。明年试试,当泛型添加到 Go 1.18 时。
  • @mkopriva 你建议一个人做什么?重复例如每种类型的SafeSet
  • type SafeSet map[interface{}]interface{} ; x := make(SafeSet)?
  • @SebastianNielsen 是的,如果这是我需要的,我会这样做。标准库中有类似的例子,比如database/sql中的NullXxx类型。

标签: go generics


【解决方案1】:

当前的 Go 版本 1.17 无法做到这一点。不幸的是,没有什么可说的了。


在将泛型添加到语言中之后,可能在 Go 1.18(2022 年初)中,根据当前接受的提议,这种参数化类型的语法将是:

type SafeSet[T comparable] struct {
    Values map[T]bool
}

特别是:

  • type constraint 位于类型名称 T 之后
  • 如果要使用T 作为映射键,则必须使用内置约束comparable,因为映射键必须具有可比性——即支持== 运算符。

然后你必须 instantiate 带有实际类型参数的参数化类型:

例子:

要使用泛型类型,您必须提供类型参数。这称为实例化。类型参数像往常一样出现在方括号中。当我们通过为类型参数提供类型参数来实例化一个类型时,我们会生成一个类型,其中类型定义中的类型参数的每次使用都会被相应的类型参数替换。

    s0 := SafeSet[net.Conn]{Values: make(map[net.Conn]bool)}
    s1 := SafeSet[string]{Values: make(map[string]bool)}
    s2 := SafeSet[int]{Values: make(map[int]bool)}

由于实例化 SafeSet 文字看起来有点冗长,您可以使用通用构造函数 func:

func NewSafeSet[T comparable]() SafeSet[T] {
    return SafeSet[T]{Values: make(map[T]bool)}
}

显然,语法是相同的,只是在这种情况下,您使用类型 arg 显式实例化函数:

    s3 := NewSafeSet[uint64]()
    s3.Values[200] = true

Gotip 游乐场:https://gotipplay.golang.org/p/Qyd6zTLdkRn

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-03
    • 2017-03-15
    • 1970-01-01
    • 2015-06-30
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多