【发布时间】:2020-08-03 12:50:12
【问题描述】:
我正在尝试在 Go 中使用接口来获得两个优势:
- 保护自己不要混淆变量顺序
- 使包彼此独立,所以有一天我可以轻松替换其中一个。
在我的特殊情况下,我可以找到 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)
在这种情况下我必须解决:
- 从其中一个包中导入
Account接口。 - 在标准 go 类型中定义函数接收值,例如
(UserID, AccoutID, OtherID int64)。
在第一种情况下,我在包中失去了独立性,并且在将来我无法在不重写一些代码的情况下替换Accounter 接口(不是很多代码,但仍然如此),在第二种情况下,如果我会有很多Account 中的类似方法和大量参数,我可能会不小心混淆变量的顺序。例如不小心将AccountID 用作UserID。
现在的问题是:有什么方法可以拥有所有优势吗?避免混淆变量顺序并避免从一个包导入到另一个包。
【问题讨论】:
-
这是两个独立包中的独立接口,它们并不相同。在单个包中定义接口并从另一个包中重用它。如果要分离这两个包,请使用仅包含接口的第三个包。
-
@Marc 谢谢。嗯,第三个包好像有点麻烦,不过是个解决办法。
-
不要解决你可能只有“一天”的问题。除非您正在设计 API,否则您以后可以随时移动/替换包。