【问题标题】:Interface method with multiple return types具有多种返回类型的接口方法
【发布时间】:2017-07-12 11:06:45
【问题描述】:

我正在为接口而苦苦挣扎。考虑一下:

type Generatorer interface {
    getValue() // which type should I put here ? 
}

type StringGenerator struct {
    length         int
}

type IntGenerator struct {
    min            int
    max            int
}

func (g StringGenerator) getValue() string {
    return "randomString"
}

func (g IntGenerator) getValue() int {
    return 1
}

我希望 getValue() 函数返回 stringint,具体取决于它是从 StringGenerator 还是 IntGenerator 调用的

当我尝试编译时,我收到以下错误:

不能在数组中使用 s (type *StringGenerator) 作为类型 Generatorer 或 切片文字: *StringGenerator 没有实现 Generatorer(getValue 方法的类型错误)

有 getValue() 字符串
想要getValue()

我怎样才能做到这一点?

【问题讨论】:

  • 你想达到什么目的?你会如何在 Java 中做同样的事情?可以根据实现返回不同内容的接口有什么用?对我来说,这听起来不太适合接口(无论是在 Go 中还是在 Java 中)。
  • @VincentvanderWeele 我已经在 stackreview 上提交了我的代码:codereview.stackexchange.com/questions/168955/…。这个问题解释了项目的目标以及为什么我需要接口来解决我的问题!
  • 啊,一切都是动态的,这就解释了! Go 的主要优势在于静态类型问题,所以我想说这个问题不是该语言的最佳匹配。当然这是可能的,就像在 Java 中一样,reflection 很可能是解决方案。

标签: object go interface


【解决方案1】:

可以通过这种方式实现:

type Generatorer interface {
    getValue() interface{}
}

type StringGenerator struct {
    length         int
}

type IntGenerator struct {
    min            int
    max            int
}

func (g StringGenerator) getValue() interface{} {
    return "randomString"
}

func (g IntGenerator) getValue() interface{} {
    return 1
}

空接口允许每个值。这允许使用通用代码,但基本上会阻止您使用非常强大的 Go 类型系统。

在您的示例中,如果您使用 getValue 函数,您将获得一个 interface{} 类型的变量,如果您想使用它,您需要知道它实际上是字符串还是 int:您将需要很多 reflect 让你的代码变慢。

来自 Python,我习惯于编写非常通用的代码。在学习围棋时,我不得不停止这种想法。

在你的具体情况下这意味着什么我不能说,因为我不知道 StringGeneratorIntGenerator 的用途。

【讨论】:

  • 我的情况类似,尽管略有不同。在我的例子中,getValue 会返回一个(不同的)结构,但是这两个不同的结构最后会返回相同的结构。所以这是相当确定的,但似乎我也不能轻易做到这一点。
  • 这些结构有什么作用?它们有什么共同点,您希望它们从同一个函数中返回?如果您能回答这个问题,请创建一个具有它们共有的功能的接口,并在两个结构上实现这些功能。那么getValue可以返回那个接口(不是空接口),你就不需要反射了。
  • 好的,这里是背景。这两个struct略有不同,我们是金融的,一个是关于trade struct,另一个是transfer struct,目的是计算最后的数量。此外,交易结构应实现一些与传输结构不同的特定功能,反之亦然。无论如何,最后他们会返回一个数量。所以这个接口的概念很好,但我不能来做类似qty(trade{}).calculateForX().get() 的事情,其中​​ qty() 和 get() 都可以从两个结构体中调用,但 calculateForX() 是一种仅用于交易结构体的方法。 .
  • 所以我的情况与 OP 完全一样,每个结构最后都应返回不同的类型,这只是一个更高级的用例。我目前的解决方法是像qtyGetForTrade(trade{}).calculateForX().get()那样没有界面,并有另一个传输功能,它不那么漂亮......
  • @ChristopheVidal:你能在这里创建一个新问题,以便我可以正确回答吗?这更容易,因为我想提出一个代码提案。最好在这里链接问题。
【解决方案2】:

您无法以您想要的方式实现这一目标。但是,您可以将函数声明为

type Generatorer interface {
    getValue() interface{}
}

如果您希望它在不同的实现中返回不同的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2016-04-20
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 2016-03-15
    相关资源
    最近更新 更多