英文:
Why can't Go functions return a type with a constrained type parameter?
问题
在尝试在Go中在编译时强制执行有效状态转换的问题上,我遇到了一个限制:函数不能返回具有非具体类型参数的通用类型。在这个问题中有详细说明。以下是一个无法构建的最小可复现示例(Go playground链接):
type MyStruct[T any] struct {
MyField T
}
func returnConstrainedGeneric[T any]() MyStruct[T] {
return MyStruct[int]{
MyField: 1,
}
}
编译器返回错误信息:cannot use MyStruct[int]{…} (value of type MyStruct[int]) as MyStruct[T] value in return statement
。
链接的问题给出了以下解释:
> 错误发生的原因是涉及类型参数的操作(包括赋值和返回)必须对其类型集中的所有类型都有效。
它提供了一些解决方法,包括类型断言,但我对为什么存在这种限制感到好奇。从直觉上讲,在我的示例中,我期望从returnConstrainedGeneric()
返回类型为MyStruct[int]
的值是有效的,因为int
满足any
的类型约束。我期望returnConstrainedGeneric()
的调用者不知道返回的值的类型是MyStruct[int]
,它只知道它是一个满足any
约束的MyStruct[T]
类型。在我的推理中,我漏掉了什么?这是Go如何实现泛型/类型约束的一个基本问题,还是Go编译器当前实现的问题,或者其他原因导致的?
英文:
While working on a problem with trying to enforce valid state transitions at compile time in Go, I've run into the limitation that a function can't return a generic type with a non-concrete type parameter, as outlined in this question. MRE that fails to build (Go playground link):
type MyStruct[T any] struct {
MyField T
}
func returnConstrainedGeneric[T any]() MyStruct[T] {
return MyStruct[int]{
MyField: 1,
}
}
The compiler returns the error cannot use MyStruct[int]{…} (value of type MyStruct[int]) as MyStruct[T] value in return statement
.
The linked question gives this reasoning:
> The error occurs because operations that involve a type parameter (including assignments and returns) must be valid for all types in its type set.
It outlines a couple of workarounds including type assertions, but I'm curious about why this restriction is in place. Naively, in my example, I would expect that's it valid to return a value of type MyStruct[int]
from returnConstrainedGeneric()
, because int
satisfies the type constraint of any
. I'd expect that a caller of returnConstrainedGeneric()
wouldn't know that the returned value was of type MyStruct[int]
, it'd just know that it's a MyStruct[T]
where T
meets the any
constraint. What am I missing in my reasoning? Is this a fundamental issue with how Go implements generics/type constraints, an issue with the current implementation of the Go compiler, or something else?
答案1
得分: 4
这是无效的,因为语法意味着:
x:=returnConstrainedGeneric[string]()
// x 是 MyStruct[string]
但你试图返回一个 MyStruct[int]
。
你推理的缺陷在于你在实例化函数时指定了返回类型。函数不能返回满足 any
约束的类型,它返回的是实例化时的类型。换句话说,函数实例化时的 T
必须与 MyStruct[T]
中的 T
相同。
如果你总是返回 MyStruct[int]
,请声明为:
func returnConstrainedGeneric[T any]() MyStruct[int] {...}
或者,如果函数根本不使用 T
:
func returnConstrainedGeneric() MyStruct[int] {...}
英文:
This is invalid because the syntax means that
x:=returnConstrainedGeneric[string]()
// x is MyStruct[string]
but you are trying to return a MyStruct[int]
.
The flaw in your reasoning is that you specify the return type of the function when you instantiate it. The function cannot return a type that satisfies the any
constraint, it returns the type that it is instantiated for. In other words, the T
the function is instantiated has to be the same T
in MyStruct[T]
.
If you always return MyStruct[int]
, declare it as such:
func returnConstrainedGeneric[T any]() MyStruct[int] {...}
or, if the function doesn't use T
at all:
func returnConstrainedGeneric() MyStruct[int] {...}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论