我正在玩Go,发现一个我无法解决的问题。假设我有如下代码:
// Imagine this is an external package for querying MySQL: I run a query // and it gives me back a struct with a method "Result" to get the result // as a string // I can NOT modify this code, since it is an external package package bar type MySQL struct {} func (m *MySQL) RunQuery() *MySQLResult { return &MySQLResult{} } type MySQLResult struct {} func (r *MySQLResult) Result() string { return "foo" }
我导入了软件包并开始使用它:
// I created a little runner to help me func run(m *bar.MySQL) string { return m.RunQuery().Result() } func main() { m := &bar.MySQL{} fmt.Println(run(m)) // Prints "foo" }
我真的很喜欢我的助手“运行”,但是我想使其更加慷慨:我不希望人们总是向我传递MySQL客户端。可以是具有“ RunQuery”和“ Result”方法的任何东西。所以我尝试使用接口:
type AnyDB interface { RunQuery() interface{ Result() string } } func run(m AnyDB) string { return m.RunQuery().Result() }
可悲的是,这不再编译了。我收到此错误:
cannot use m (type *MySQL) as type AnyDB in argument to run: *MySQL does not implement AnyDB (wrong type for RunQuery method) have RunQuery() *MySQLResult want RunQuery() interface { Result() string }
Go不支持此功能吗,或者我做错了什么?
RunQuery 应该返回接口,否则你总是要处理强类型。
RunQuery
AnyDB 不是必需的,我为此添加了内容。
AnyDB
AnyResult应该在bar包中定义或导入其中。
AnyResult
bar
type AnyDB interface { RunQuery() AnyResult } type MySQL struct{} func (m *MySQL) RunQuery() AnyResult { return &MySQLResult{} } type AnyResult interface { Result() string } type MySQLResult struct{} func (r *MySQLResult) Result() string { return "foo" }