当前位置: 首页 > 面试题库 >

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

陆洲
2023-03-14
问题内容

我正在玩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 应该返回接口,否则你总是要处理强类型。

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


 类似资料:
  • 我正在尝试返回一个对象,它应该是IClass的一个实现,具有一个通用类型,是IType的一个实现。 我要返回的实际类扩展了Class (abstract ),其泛型类型为ActualType: 抽象类对象实现了IClass接口,可以有任何扩展IType的类型 ActualType只是实现了IType接口 我在编译时得到一个“类型不匹配:无法从ActualClass转换为IClass”错误。我不明白

  • 问题内容: 我在接口上苦苦挣扎。考虑一下: 我希望函数返回a 或an ,具体取决于是否从或调用 当我尝试对此进行编译时,出现以下错误: 不能将s( StringGenerator类型)用作数组或切片文字中的Generator类型: StringGenerator不实现Generatorer(getValue方法的类型错误) 有getValue()字符串 要getValue() 我该如何实现? 问题

  • 这是一个来自第三方库API的真实示例,但经过了简化。 用Oracle JDK 8U72编译 考虑以下两种方法: 两者都报告了一个“未经检查的强制转换”警告--我知道原因了。让我困惑的是为什么我可以打电话 试图传递会出现错误,正如所料: 如果报告为错误,为什么不是?

  • 问题内容: 如何在实现类中强制执行方法getFoo(),返回相同实现类类型的列表。 现在,实现Bar的类将返回实现Bar的任何类的对象。我想使其更加严格,以便实现Bar的类在getFoo()中仅返回其类型的对象列表。 问题答案: 不幸的是,这不能由Java的类型系统强制执行。 但是,您可以通过使用以下方法来达到非常接近的效果: 然后您的实现类可以像这样实现它: 但是没有什么可以阻止另一个类这样做:

  • 这些语句(接口vs类型)有什么区别?

  • 问题内容: 假设我正在设计类似以下界面的内容: 但是,需要注意的是,for的返回类型和参数匹配具体的实现,而不仅仅是。也就是说,如果我具有该实现,则需要具备以下条件: 如上所述,不会引起任何编译错误,但是不能保证在所有实现中返回类型都匹配。当然,甚至不会编译,因为签名与接口不匹配。 一种候选解决方案是在泛型中使用自引用或递归范围: 这将使我得到我想要的东西,但有一个例外:其他实现可能传递错误的泛型