具体类型与返回类型上的接口不匹配

时间:2018-12-07 01:00:46

标签: go

我正在玩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不支持此操作吗,还是我做错了什么?

1 个答案:

答案 0 :(得分:2)

RunQuery应该返回接口,否则您始终必须处理强类型。

{AnyDB不是必需的,为了方便起见,我添加了它。

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"
}