英文:
I want to create interface for dig
问题
我是一个Go语言的新手。
我想要抽象出服务容器的实现:
type Container interface {
Provide(constructor interface{}, opts ...interface{}) error
Invoke(function interface{}, opts ...interface{}) error
}
但是出现了一个错误:
#13 0.387 cmd/app/main.go:26:40: cannot use container (type *dig.Container) as type application.Container in argument to application.NewApplication:
#13 0.387 *dig.Container does not implement application.Container (wrong type for Invoke method)
#13 0.387 have Invoke(interface {}, ...dig.InvokeOption) error
#13 0.387 want Invoke(interface {}, ...interface {}) error
我做错了什么?
我应该如何正确声明接口?
英文:
I'm a novice in golang.
I want to abstract from the implementation of the service container:
type Container interface {
Provide(constructor interface{}, opts ...interface{}) error
Invoke(function interface{}, opts ...interface{}) error
}
but an error occurs:
#13 0.387 cmd/app/main.go:26:40: cannot use container (type *dig.Container) as type application.Container in argument to application.NewApplication:
#13 0.387 *dig.Container does not implement application.Container (wrong type for Invoke method)
#13 0.387 have Invoke(interface {}, ...dig.InvokeOption) error
#13 0.387 want Invoke(interface {}, ...interface {}) error
What am I doing wrong?
How I can declare interface correct?
答案1
得分: 2
这意味着*dig.Container
不能满足application.Container
接口的要求。它进一步解释了application.Container
要求Invoke
方法接受一个可变参数的interface{}
列表,但*dig.Container
接受一个可变参数的dig.InvokeOption
列表。
尽管空接口可以存储任何类型,但这并不意味着任何切片类型自动成为空接口切片(这是泛型的一个重要动机,很快就会推出)。
我记得我自己也曾对此感到困惑。考虑以下代码:
package main
import (
"fmt"
)
type T struct{}
func main() {
var Ts = []T{
T{}, T{}, T{},
}
fmt.Println(Ts...)
}
它将无法编译,即使每个单独的T
都满足interface{}
,因为[]T
不是[]interface{}
:
./prog.go:13:16: cannot use Ts (type []T) as type []interface {} in argument to fmt.Println
最简单的解决方案是使dig.Container
的Invoke
函数与application.Container
的Invoke
签名匹配。您仍然可以将*dig.InvokeOption
列表传递给它,这些列表分别满足interface{}
。您仍然需要在dig.Container.Invoke
内将interface{}
转换回*dig.InvokeOption
。
英文:
Cannot use container (type *dig.Container) as type application.Container in argument to application.NewApplication:
*dig.Container does not implement application.Container (wrong type for Invoke method)
have Invoke(interface {}, ...dig.InvokeOption) error
want Invoke(interface {}, ...interface {}) error
This means *dig.Container
doesn't satisfy the interface application.Container
. It goes on to explain that application.Container
requires the Invoke
method to take a variadic list of interface{}
, but *dig.Container
takes a variadic list of dig.InvokeOption
.
Even though an empty interface can store any type, that does not mean that any slice type is automatically also a slice of empty interfaces (That's a big motivation for Generics, which should come out soon).
I remember being confused by this myself. Consder this code:
package main
import (
"fmt"
)
type T struct{}
func main() {
var Ts = []T{
T{}, T{}, T{},
}
fmt.Println(Ts...)
}
It will not compile, even thought each individual T
satisfies interface{}
because a []T
is not an []interface{}
:
> ./prog.go:13:16: cannot use Ts (type []T) as type []interface {} in argument to fmt.Println
The easiest solution here would be to make dig.Container
's Invoke
function match the Invoke
signature of application.Container
. You can still pass it a list of *dig.InvokeOption
s, which individually satisfy interface{}
. You'll still have to convert the interface{}
s back to *dig.InvokeOption
s within dig.Container.Invoke
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论