Golang – 无法从接口实现中推断出 T 的类型?

huangapple go评论75阅读模式
英文:

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()什么也不做,只是返回自身-从功能上讲,s1s1.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.

huangapple
  • 本文由 发表于 2022年9月5日 18:36:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/73608031.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定