【问题标题】:Golang Interface with functions receiving specified Interface args具有接收指定接口参数的函数的 Golang 接口
【发布时间】:2020-08-03 12:50:12
【问题描述】:

我正在尝试在 Go 中使用接口来获得两个优势:

  1. 保护自己不要混淆变量顺序
  2. 使包彼此独立,所以有一天我可以轻松替换其中一个。

在我的特殊情况下,我可以找到 workaroung,但我不明白为什么我尝试的方式行不通,这似乎简单且合乎逻辑。

这就是我的工作。

在一个包(命名处理程序)中,我有一个描述我需要的函数的接口,只是接收Account 的东西。

package handlers

type Accounter interface {
    AddAccount(a Account)
}

type Account interface {
    AccountID() int64
    UserID() int64
    OtherID() int64

}

在我程序的其他包(名为 accounter)中,我有与接口匹配的函数,并定义了Account 接口以避免从第一个包中导入此接口。

package accounter

type Account interface {
    AccountID() int64
    UserID() int64
    OtherID() int64
}

func (x *accounter) AddAccount(a Account) {
...
}

但是go vet 告诉我我不能这样做:

configure_stats_loader.go:109:64: cannot use x (type *accounter.Accounter) as type handlers.Accounter in argument to handlers.AddAccHandler:
    *accounter.Accounter does not implement handlers.Accounter (wrong type for AddAccount method)
        have AddAccount(accounter.Account)
        want AddAccount(handlers.Account)

在这种情况下我必须解决:

  1. 从其中一个包中导入Account 接口。
  2. 在标准 go 类型中定义函数接收值,例如 (UserID, AccoutID, OtherID int64)

在第一种情况下,我在包中失去了独立性,并且在将来我无法在不重写一些代码的情况下替换Accounter 接口(不是很多代码,但仍然如此),在第二种情况下,如果我会有很多Account 中的类似方法和大量参数,我可能会不小心混淆变量的顺序。例如不小心将AccountID 用作UserID

现在的问题是:有什么方法可以拥有所有优势吗?避免混淆变量顺序并避免从一个包导入到另一个包。

【问题讨论】:

  • 这是两个独立包中的独立接口,它们并不相同。在单个包中定义接口并从另一个包中重用它。如果要分离这两个包,请使用仅包含接口的第三个包。
  • @Marc 谢谢。嗯,第三个包好像有点麻烦,不过是个解决办法。
  • 不要解决你可能只有“一天”的问题。除非您正在设计 API,否则您以后可以随时移动/替换包。

标签: go interface


【解决方案1】:

呼应@Marc cmets,“第三方”包非常适合定义常见类型。这是常见的做法,尤其是在处理 gRPC generated code 时。

同样根据Effective Go 保持接口简短:

只有一种或两种方法的接口在 Go 代码中很常见

因此,请避免繁琐的 getter/setter 定义 - 并专注于更大的操作。所以我建议在你的“类型”包中:

package mydefs

// concrete type: used for Creation and lookup
type Account struct {
    ID      int64
    UserID  int64
    OtherID int64
}

// abstract interface: keep method list short
type Accounter interface {
    Add(a Account) error             //
    Get(a Account) (Account, error)  // use concrete type as a lookup request type
}

【讨论】:

    猜你喜欢
    • 2021-10-07
    • 2018-03-22
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 2016-12-20
    • 1970-01-01
    • 2021-04-19
    相关资源
    最近更新 更多