【问题标题】:How to implement interface from a different package in golang?如何在golang中实现不同包的接口?
【发布时间】:2017-11-04 21:45:25
【问题描述】:

我是 golang 的初学者,正在尝试接口。我想将接口保存在单独的包中,以便我可以使用它在各种其他包中实现它,也将它提供给其他团队(.a 文件),以便他们可以实现自定义插件。请参阅下面的示例了解我想要实现的目标。

--- Folder structure ---
gitlab.com/myproject/
                  interfaces/
                            shaper.go
                  shapes/
                        rectangle.go
                        circle.go

---- shaper.go ---
package interfaces

type Shaper interface{

    Area() int

}

如何确保 rectangle.go 实现 shaper 接口? 我知道 go 隐式实现了接口,这是否意味着 rectangle.go 会自动实现 shaper.go,即使它在不同的包中?

我像下面这样尝试过,但是当我运行 gofmt 工具时,它会删除导入,因为它未使用。

--- rectangle.go ---
package shapes

import "gitlab.com/myproject/interfaces"

type rectangle struct{

  length int
  width int
}

func (r rectangle) Area() int {
 return r.length * r.width
}

提前致谢。

【问题讨论】:

  • “它没有用”是什么意思?
  • 您可以像其他任何东西一样引用其他包中的接口(在您的情况下为interfaces.Shaper)。我认为这个问题没有任何真正的问题;你应该澄清你有什么问题(最好通过minimal reproducible example)。
  • 我已经解释了更多关于我面临的问题。我认为这是一个最小的完整且可验证的示例。你能用代码解释一下在这种情况下引用或实现接口的例子吗?提前致谢。
  • 不需要导入接口。在哪里实现接口并不重要——只在它被使用的地方。有更多关于接口herehere的信息
  • @Sanketh 是的,接口既不必在同一个包中,也不必为实现它的类型导入。

标签: go


【解决方案1】:

关于接口有一个很棒的section in the go wiki

Go 接口通常属于使用接口类型值的包,而不是实现这些值的包。实现包应该返回具体的(通常是指针或结构)类型:这样,新方法可以添加到实现中而无需大量重构。

这还有一个好处是它减少了包之间的耦合(通过不强迫任何人只为接口导入你的包)并且它通常会导致更小的接口(通过允许人们只使用你想要的接口的一个子集已建成)。

如果您是新手,我强烈建议您阅读我链接的“Go Code Review Comments”wiki 文章,如果您有更多时间,还可以阅读 Effective Go。愉快的黑客攻击!

【讨论】:

  • 我经常看到这个建议没有被遵循。比如在net/http中,handler接口需要ServeHTTP,由ServeMux和HandlerFunc实现。 golang.org/pkg/net/http/#ServeMux.ServeHTTP
  • ServerMux 确实实现了 http.Handler 接口,但同时这种类型使用该接口让调用者注入她想要的处理程序接口(例如通过ServeMux.Handle(…) 函数。
  • 你是否也推荐阅读dave.cheney.net/2016/08/20/solid-go-design
【解决方案2】:

假设您有一个使用Shaper 的函数。您可以使用rectangle 测试该功能,并通过这样做确保实现:

func DoStuff(s Shaper) {
    s.Area()
}

func TestDoStuff(t *testing.T) {
    var s Shaper = rectangle{length: 5, width: 3}
    DoStuff(s)
    // assertion
}

如果rectangle 没有实现Shaper,你会得到这样的错误:

cannot use rectangle literal (type rectangle) as type Shaper in assignment:
rectangle does not implement Shaper (missing Area method)

Effective Go:

Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here.

【讨论】:

    猜你喜欢
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 2021-11-02
    • 2021-07-21
    • 1970-01-01
    相关资源
    最近更新 更多