为什么两个具有相同方法的命名接口(interface)被视为不同的接口(interface) - 如何避免这种情况?
假设我们有一个喜欢吃产品的人 (Eater)。他不在乎他吃什么产品,他只想被人指出他可以从哪里买到新产品。换句话说,他想要产品服务,但不关心产品服务会生产什么产品。具体实现中我们会尝试给他吃苹果,所以我们会给他提供appleService。
结果如下:
./main.go:9: cannot use appleService (type *service.AppleService) as type eater.ProductServiceI in function argument:
*service.AppleService does not implement eater.ProductServiceI (wrong type for New method)
have New() service.ProductI
want New() eater.ProductI
接口(interface) service.AppleI
和 eater.AppleI
具有相同的方法 Eat()
并且 golang 将它们视为不同的方法。为什么以及如何避免这种情况?根据鸭子类型,这应该有效,因为 ProductServiceI
实际需要的是提供的结构具有 Eat()
方法 - 它不应该关心什么名称具有接口(interface)( service.ProductI
与 eater.ProductI
)。
完整代码如下:
==> ./main.go <==
package main
import "./apple/service"
import "./eater"
func main() {
appleService := &service.AppleService{}
// func eater.New(productService ProductServiceI)
appleEater := eater.New(appleService)
appleEater.EatUntilHappy()
}
==> ./eater/eater.go <==
package eater
type ProductServiceI interface {
New() ProductI
}
type ProductI interface {
Eat()
}
type Eater struct {
productService ProductServiceI
}
func New(productService ProductServiceI) *Eater {
return &Eater{
productService: productService,
}
}
func (a *Eater) EatUntilHappy() {
for i:=0; i < 5; i++ {
product := a.productService.New()
product.Eat()
}
}
==> ./apple/service/service.go <==
package service
import "./apple"
type ProductI interface {
Eat()
}
type AppleService struct {
}
func (a *AppleService) New() ProductI {
return &apple.Apple{}
}
==> ./apple/service/apple/apple.go <==
package apple
import "fmt"
type Apple struct {
}
func (a *Apple) Eat() {
fmt.Println("mniam, mniam")
}
我认为只要声明相同,什么名称或什么导入路径有接口(interface)都没有关系。
最佳答案
我认为你这里有几个问题。首先,您定义了 AppleI
接口(interface)两次,一次在 main 中,一次在 service 中。其次,你似乎在尝试做 Python 或 Java(我猜)风格的包。值得一读 packages
这是编译和运行的代码版本。
==> kamil/main.go
package main
import (
"kamil/service"
)
type Program struct {
appleService service.AppleServiceI
}
func main() {
program := &Program{
appleService: &service.AppleService{},
}
apple := program.appleService.New()
apple.Eat()
}
==> kamil/service/service.go
package service
import (
"kamil/service/apple"
)
type AppleServiceI interface {
New() AppleI
}
type AppleI interface {
Eat()
}
type AppleService struct {
}
func (a *AppleService) New() AppleI {
return &apple.Apple{}
}
==> kamil/service/apple/apple.go(未更改)
package apple
import "fmt"
type Apple struct {
}
func (a *Apple) Eat() {
fmt.Println("mniam, mniam")
}
就是说,我不认为您采用的方法是惯用的 GO,您最终可能会在某个时候撞到头 :)
关于go - 接口(interface)具有相同的方法,但被认为是不同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21166113/