英文:
Method on struct with generic variable
问题
我有以下使用泛型的代码。我知道不能在方法中使用泛型,但可以在类型中使用。从技术上讲,我的代码符合这两个限制,但仍然出现错误。
./main.go:12:9: 无法使用未实例化的泛型类型 GenericCacheWrapper[T any]
。
实例化在 main 函数的第一行。
有没有办法实现这个?这可能被认为是 Golang 的一个 bug 吗?
package main
import (
"encoding/json"
"fmt"
)
type GenericCacheWrapper[T any] struct {
Container T
}
func (c GenericCacheWrapper) MarshalBinary() (data []byte, err error) {
return json.Marshal(c.Container)
}
func (c GenericCacheWrapper) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, &c.Container)
}
func main() {
wrapper := GenericCacheWrapper[int]{Container: 4}
data, err := wrapper.MarshalBinary()
if err != nil {
panic(err)
}
fmt.Println(data)
}
https://go.dev/play/p/9sWxXYmAcUH
英文:
I have following code that uses generics. I know that one can't use generics with methods, but can with types. Technically, my code complies with both restrictions, but still I get en error
./main.go:12:9: cannot use generic type GenericCacheWrapper[T any] without instantiation
The instantiation is on the first line of main function.
Is there any way to achieve this? May this be considered a Golang bug?
import (
"encoding/json"
"fmt"
)
type GenericCacheWrapper[T any] struct {
Container T
}
func (c GenericCacheWrapper) MarshalBinary() (data []byte, err error) {
return json.Marshal(c.Container)
}
func (c GenericCacheWrapper) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, &c.Container)
}
func main() {
wrapper := GenericCacheWrapper[int]{Container: 4}
data, err := wrapper.MarshalBinary()
if err != nil {
panic(err)
}
fmt.Println(data)
}
答案1
得分: 4
你只需要在GenericCacheWrapper
的末尾添加[T]
,或者如果你想明确表示在函数中实际上没有使用T
,则添加[_]
。
package main
import (
"encoding/json"
"fmt"
)
type GenericCacheWrapper[T any] struct {
Container T
}
func (c GenericCacheWrapper[T]) MarshalBinary() (data []byte, err error) {
return json.Marshal(c.Container)
}
func (c GenericCacheWrapper[T]) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, &c.Container)
}
func main() {
wrapper := GenericCacheWrapper[int]{Container: 4}
data, err := wrapper.MarshalBinary()
if err != nil {
panic(err)
}
fmt.Println(data)
}
这个规则在语言规范中定义:
一个泛型类型也可以有与之关联的方法。在这种情况下,方法的接收者必须声明与泛型类型定义中相同数量的类型参数。
但是背后的原因并不是很清楚,可能是为了使编译器/类型检查器的实现更容易。
相关链接:https://stackoverflow.com/questions/71274361/go-error-cannot-use-generic-type-without-instantiation
英文:
You just have to add [T]
to the end of GenericCacheWrapper
or [_]
if you want to make it clear that you are not actually using T
in the functions.
package main
import (
"encoding/json"
"fmt"
)
type GenericCacheWrapper[T any] struct {
Container T
}
func (c GenericCacheWrapper[T]) MarshalBinary() (data []byte, err error) {
return json.Marshal(c.Container)
}
func (c GenericCacheWrapper[T]) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, &c.Container)
}
func main() {
wrapper := GenericCacheWrapper[int]{Container: 4}
data, err := wrapper.MarshalBinary()
if err != nil {
panic(err)
}
fmt.Println(data)
}
This rule is defined in the language spec:
> A generic type may also have methods associated with it. In this case, the method receivers must declare the same number of type parameters as present in the generic type definition.
But the reason behind this isn't very clear, perhaps to make implementation of the compiler/type checking easier.
Related: https://stackoverflow.com/questions/71274361/go-error-cannot-use-generic-type-without-instantiation
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论