【发布时间】:2021-11-25 12:50:51
【问题描述】:
我已经开始尝试 Go 泛型。有没有办法定义一个泛型例如:一个方法不需要用指针接收器调用,另一个需要用指针接收器调用。
例子:
type MapKey interface {
comparable
}
type Unmarshaller[T any] interface {
UnmarshalJSON(b []byte) error
*T
}
type Marshaller[T any] interface {
MarshalJSON() ([]byte, error)
}
type MapValue[T any] interface {
Marshaller[T]
Unmarshaller[T]
}
type Map[T any, K MapKey, V MapValue[T]] struct {
_ K
_ V
}
func (m Map[K, V]) Save(k K, v V) error {
_, _ = v.MarshalJSON()
return nil
}
func (m Map[K, V]) Get(k K) (value V, err error) {
v := new(V)
err = v.UnmarshalJSON(m.bytesFromKey(k))
return *v, nil
}
// here I need to make sure V is actually a pointer so that UnmarshalJSON correctly propagates to the caller of GetTo and no copy is made of V
func (m Map[K, V]) GetTo(k K, v V) error {
bytesValue := m.kv.Get(m.bytesFromKey(k))
return v.UnmarshalJSON(v)
}
错误:
./map_generic.go:26:16: V has no constraints
./map_generic.go:27:11: v.MarshalJSON undefined (type bound for V has no method MarshalJSON)
./map_generic.go:31:16: V has no constraints
./map_generic.go:33:10: v.UnmarshalJSON undefined (type *V has no field or method UnmarshalJSON)
【问题讨论】:
-
尝试解释你这样做的目的,因为我什至不知道那些
func和type声明是否有效。 -
您在此处发布的代码无法编译,但这是由于与您的问题中的约束无关的几个问题。请提出一个最小的可重现示例
-
如果你的问题是关于指针而没有指针的方法,这个参考可以帮助你stackoverflow.com/questions/33936081/…
-
无论如何,我相信你不能可靠地做到这一点。
*T的方法集包括在T上声明的方法,因此即使您将类型参数约束为*T,如果您在T或*T上声明UnmarshalJSON,它也将起作用。 -
那么你可能不需要泛型。不要过度复杂化。只需立即将 V 声明为接口类型,如
JSONer,定义为type JSONer interface { UnmarshalJSON([]byte) error; MarshalJSON() ([]byte, error) },并让实现者决定是使用指针还是值接收器。