go - 有没有办法检查值是否满足接口(interface)中定义的类型约束?

标签 go type-constraints

例如我定义了如下接口(interface):

type MyTypeConstraint interface {
    ~int | ~string
}

除了使用 switch reflect.TypeOf(v) 语句将值与 MyTypeConstraint 中的每种类型进行比较之外,是否有一种方法可以检查给定值是否满足此约束条件?例如,这里我不希望用户将类型不满足约束的 v 传递给函数:

type ErrNode struct {
    Data map[string]interface{}
    // Err  error -- irrelevant
    // next *ErrNode -- irrelevant
}

// `GetData()` is constrained but `Set()` is not.
// Of course I could pass `ErrNode` as parameter into `Set()` 
// like bellow but then I won't be able to chain `Set()` calls.
func GetData[T ErrData](list *ErrNode, k string) (v T, ok bool) {
    v, ok = list.Data[k].(T)
    return v, ok
}

func (e *ErrNode) Set(k string, v interface{}) (self *ErrNode) {
    e.Data[k] = v // v must be of type listed in `MyTypeConstraint`
    return e
}

最佳答案

您不能(至少在 go 1.181.19 * 中)对方法设置类型约束:

//syntax error: method must have no type parameters

func (e *ErrNode) Set[T MyTypeConstraint](k string, v T) (self *ErrNode) {
    e.Data[k] = v
    return e
}

您可以对函数施加类型约束:

func Setter[T MyTypeConstraint](e *ErrNode, k string, v T) {
    e.Data[k] = v
}

(*) 来自 go 1.18 release notes :我们希望在未来的版本中删除此限制。 - 从 go 1.19 开始,这仍然是不允许的:

The Go compiler only supports calling a method m on a value x of type parameter type P if m is explicitly declared by P's constraint interface. Similarly, method values x.m and method expressions P.m also are only supported if m is explicitly declared by P, even though m might be in the method set of P by virtue of the fact that all types in P implement m. We hope to remove this restriction in a future release.

关于go - 有没有办法检查值是否满足接口(interface)中定义的类型约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73195780/

相关文章:

c# - 有什么办法可以将这些几乎相同的类合并为一个吗?

pointers - Goland 调试器的问题

mysql - 如何将 Go time.Time 转换为 MySQL datetime?

go - 是否可以在 Golang 中 pickle 结构的实例

.net - F# 静态成员约束结合 IDisposable

haskell - 如何对关联数据进行约束?

haskell - 尝试理解 Haskell 的 => 与定义类型

scala - Total Collections,拒绝不包括所有可能性的类型的集合

不能用宏包装 cgo 标志

python - 如何在没有 sudo 的情况下发送自定义 'TCP' 数据包 - 没有三向握手