英文:
Is there a way to check if value satisfies type constraint defined in interface?
问题
例如,我定义了以下接口:
type MyTypeConstraint interface {
~int | ~string
}
除了使用switch reflect.TypeOf(v)
语句将值与MyTypeConstraint
中的每个类型进行比较之外,还有其他方法可以检查给定值是否满足此约束吗?例如,在这里,我不希望用户将不满足约束的类型的v
传递给函数:
type ErrNode struct {
Data map[string]interface{}
// Err error -- 不相关
// next *ErrNode -- 不相关
}
// `GetData()` 受约束,但 `Set()` 不受约束。
// 当然,我可以将 `ErrNode` 作为参数传递给 `Set()`,
// 但这样我就无法链式调用 `Set()`。
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 必须是 `MyTypeConstraint` 中列出的类型之一
return e
}
英文:
For example I defined the following interface:
type MyTypeConstraint interface {
~int | ~string
}
Is there a way to check if given value satisfies this constraint aside from comparing value to each type inside MyTypeConstraint
using switch reflect.TypeOf(v)
statement? For example, here I don't want user to pass v
which type doesn't satisfy constraint into function:
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
}
答案1
得分: 1
你不能在方法上使用类型约束(至少在go
的1.18
或1.19
版本中是这样的):
// 语法错误:方法不能有类型参数
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发布说明中可以看到,他们希望在将来的版本中移除这个限制。然而,截至go 1.19
,仍然不允许这样做:
Go编译器只支持在类型参数类型P的值x上调用方法m,如果m是P的约束接口明确声明的。类似地,方法值x.m和方法表达式P.m也只支持m是P明确声明的情况,即使m可能通过P的所有类型实现而在P的方法集中。我们希望在将来的版本中移除这个限制。
英文:
You cannot (at least with go
1.18
or 1.19
*) put a type constraint on a method:
//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
}
You may put a type constraint on a function:
func Setter[T MyTypeConstraint](e *ErrNode, k string, v T) {
e.Data[k] = v
}
(*) from the go 1.18 release notes: We hope to remove this restriction in a future release.
- and this still is not allowed as of 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论