gpt4 book ai didi

go - 外部包如何隐式实现接口(interface)?

转载 作者:行者123 更新时间:2023-12-05 05:50:09 27 4
gpt4 key购买 nike

我正在编写一段依赖于某些实现的代码。
我想将实现与我的代码分离,并使实现尽可能独立。
我想通过使用接口(interface)而不是具体类型来实现这种方法,如下所示:

package mypackage

type MyType interface {
Title() string
Price() int
}

type TypeGetter interface {
GetType() MyType
}

func MyHandler(tg TypeGetter) {
t := tg.GetType()
fmt.Printf("Title: %s, Price: %d", t.Title(), t.Price())
}

实现可能是这样的:

package external

// CustomType implicitly implements the MyType interface
type CustomType struct {
title string
price int
}
func (t CustomType) Title() string { return t.title }
func (t CustomType) Price() int { return t.price }


// CustomTypeGetter implicitly implements the TypeGetter interface. Or is it???
type CustomTypeGetter struct {
}
func (g CustomTypeGetter) GetType() CustomType {
return CustomType{"Hello", 42}
}

然后,代码会做这样的事情:

package main

import "mypackage"
import "external"

func main() {
tg := external.CustomTypeGetter{}
mypackage.MyHandler(tg) // <--- the compiler does not like this
}

我希望这个例子不言而喻:我在“mypackage”和“external”包之间没有耦合,它们可能会被替换,用我的模拟来测试等。

问题:编译器提示对 MyHandler 的调用有一个对象实现了:
func GetType() CustomType,而不是:
func GetType() MyType

我找到的唯一解决方案是将接口(interface)声明(MyTypeTypeGetter)移动到第三个​​ 包,然后将两个“mypackage "和 "外部"包可以使用它。
但我想避免这种情况。

Go 的隐式接口(interface)实现的概念是否与第三个通用包的想法相矛盾?

有没有办法实现这样的事情,而不两个包绑定(bind)在一起?

最佳答案

Isn't Go's concept of implicit implementation of interfaces contradict the idea of a third common package?

我觉得是的。 Go 作者引入了隐式接口(interface)实现来消除包之间不必要的依赖关系。这适用于像 io.Reader 这样的简单接口(interface),但您不能将它应用到任何地方。

语言创造者之一,Rob Pike, says接口(interface)的非声明性满足并不是 Go 接口(interface)背后思想的重要组成部分。这是一个不错的功能,但并非该语言的所有元素都实用或每次都可以使用。

对于复杂的接口(interface),需要导入定义接口(interface)的包。例如,如果你想实现一个与标准库中的 sql 包一起工作的 SQL 驱动程序,你必须导入 sql/driver包。

我建议不要在项目开始时引入接口(interface)。通常,它会导致每次更新对域模型的理解时都需要解决人为问题,例如重写接口(interface)。很难从第一次尝试中得出一个好的抽象,而且在我看来,在许多情况下,这是没有必要的。

I need to query external source for products. I don't care how the external sources store the data (db, file, network). I just need a "product" type. So it's either I define a Product type, forcing the external implementations to import and use it, or the Go way - define a Product interface and let the implementations implicitly implement this interface. Which apparently doesn't work

我在这里看到两个松散相关的目标:

  1. 定义一个接口(interface)来交换产品源的实现。
  2. 实现产品源的包不应导入定义接口(interface)的包。

根据我的经验,我建议仅当您至少有一个产品源服务的有效实现时才执行第 1 点。

第 2 点并非总能实现,但没关系;请参阅上面标准 Go 库中的示例。

附言请考虑不创建 Product 界面。虽然最终提出 PorductSource 接口(interface)确实有意义,但 Product 很可能只是一组数据; struct 是表示此类信息的完美方式。请参阅 this very relevant code smaplethis article寻找灵感。

关于go - 外部包如何隐式实现接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70559038/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com