英文:
Golang - Cannot infer T from interface implementation?
问题
假设我有以下代码:
type Getter[T any] interface {
Get() T
}
type Wrapper[T any] struct {
a T
}
func (s Wrapper[T]) Get() T {
return s.a
}
在这里,你可以说Wrapper[T]
实现了Getter[T]
,因为它实现了唯一的要求Get() T
。
现在,我有一个函数需要接受一个Getter[T]
来返回内部值...
func Return[T any](i Getter[T]) T {
return i.Get()
}
var s1 = Wrapper[int]{
a: 5,
}
在这里,Return
只是获取内部值-所以期望是当我传入s1
时,我应该得到5
。
var s2 = Return(s1) // s1的类型Wrapper[int]与Getter[T]不匹配(无法推断T)
...然而,我得到了这个错误。现在,这里有一个简单的解决方法...
func (s Wrapper[T]) Getter() Getter[T] {
return s
}
var s2 = Return(s1.Getter())
这样就可以工作了。Getter()
什么也不做,只是返回自身-从功能上讲,s1
和s1.Getter()
在这里应该是相同的-但它却不起作用。T
可以在方法中推断出来,但不能作为参数。
我的问题是:我在这里做错了什么-还是这只是Go的一部分?为了使这个示例工作,我需要添加一个虚拟方法来帮助编译器吗-还是我漏掉了什么?
英文:
Say I have the following code:
type Getter[T any] interface {
Get() T
}
type Wrapper[T any] struct {
a T
}
func (s Wrapper[T]) Get() T {
return s.a
}
Here, you can say that Wrapper[T]
implements Getter[T]
- since it implements Get() T
which is the only requirement.
Now, I have a function that needs to take a Getter[T]
in order to return the internal value...
func Return[T any](i Getter[T]) T {
return i.Get()
}
var s1 = Wrapper[int]{
a: 5,
}
Here, Return
just gets the value inside - so the expectation is that when I pass in s1
, I should get 5
in return.
var s2 = Return(s1) // type Wrapper[int] of s1 does not match Getter[T] (cannot infer T)
...instead, I get that error. Now, there is an easy workaround here...
func (s Wrapper[T]) Getter() Getter[T] {
return s
}
var s2 = Return(s1.Getter())
This ends up working. Getter()
does nothing but return itself - functionally speaking, s1
and s1.Getter()
should be identical here - and yet it doesn't work. T
can be inferred in the method, but not as a parameter.
My question is this: Am I doing something wrong here - or is this just a part of Go? For this example to work, do I need to add a dummy method just to help the compiler - or am I missing something?
答案1
得分: 1
你不需要向Wrapper
添加方法,但是如果类型推断失败(编译器无法推断所有类型),你必须显式地为类型参数提供类型,就像这样:
var s2 = Return[int](s1)
Return()
函数有一个类型参数,如果你显式地为T
提供类型(这里是int
),那么编译器将能够验证s1
确实实现了Getter[int]
接口。在Go Playground上试一试。
英文:
You do not need to add methods to Wrapper
, but if type inference does not succeed (the compiler can't infer all types), you have to provide the types for the type parameters explicitly, like this:
var s2 = Return[int](s1)
The Return()
function has a type parameter, if you provide the type for T
explicitly (int
here), then the compiler will be able to validate that s1
does indeed implement the Getter[int]
interface. Try it on the Go Playground.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论