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
}
CodePudding user response:
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.