【问题标题】:Return array as interface返回数组作为接口
【发布时间】:2018-12-17 00:12:19
【问题描述】:

案例一

我有以下方法,效果很好。这里我返回一个数组作为接口。

func ReturnArrayAsInterface1() interface{} {
    retval := make([]int, 0)
    retval = append(retval, 4, 6, 8, 10)
    return retval
}

案例 2

考虑以下方法。这里我想在发生恐慌的情况下返回错误,所以我在开头定义了retval,并在defer中更改了它的值。但这会显示错误“不能使用 'retval' (type interface{}) as type []Type”

func ReturnArrayAsInterface2() (retval interface{}) {
    defer func() {
        if r := recover(); r != nil {
            retval = r
        }
    }()
    retval = make([]int, 0)
    retval = append(retval, 4, 6, 8, 10) .  // error here : Cannot use 'retval' (type interface{}) as type []Type
    return retval
}

所以我想知道的是,为什么第一个函数可以正常工作而第二个函数不能?有什么办法可以克服吗?

案例 3

这也类似于 案例 2

func ReturnArrayAsInterface3() interface{} {
    var retval interface{}
    defer func() {
        if r := recover(); r != nil {
            retval = r
        }
    }()
    retval = make([]int, 0)
    retval = append(retval, 4, 6, 8, 10) .  // error here : Cannot use 'retval' (type interface{}) as type []Type
    return retval
}

【问题讨论】:

  • 第二种和第三种情况是非常单调的 Go。如果一个函数可能返回一个值或一个错误,它应该有两个返回值,就像 Go 中的每个其他这样的函数一样 - 例如func ReturnArrayAsInterface() (interface{},error).
  • return []int{4, 6, 8, 10}
  • 哈哈哈,@dolmen。这只是我举的一个例子。实际值并不像 []int{4, 6, 8, 10} 这么简单 :) 另外我的问题不是返回该数组,而是要了解代码的工作原理!

标签: go types interface slice


【解决方案1】:

因为 Go 是一种静态类型语言。您的第一个示例有效,因为retval 的类型是[]int,因此您可以将int 值附加到它。你使用了short variable declaration,所以retval 的类型是从右边的表达式推断出来的,它显然是[]int 类型。当您返回此 []int 值时,它将自动包装在 interface{} 值中。

在第二种情况下,您使用命名结果类型,在其中明确指定其类型为interface{},并且不能将值附加到interface{} 类型的值(非切片类型)。 retval接口值中存储的值的动态类型是切片没关系,它的静态类型是interface{}

它适用于type assertion:

retval = append(retval.([]int), 4, 6, 8, 10)

但第一个解决方案更清洁、更高效。

您的第三种情况几乎与第二种情况相似:您使用variable declaration,在其中明确声明您希望retval 变量的类型为interface{}

【讨论】:

    【解决方案2】:

    情况 3 将不会像情况 2 那样在恐慌的情况下工作:在panic 的情况下,return retval 将不会运行,因此nil 将由ReturnArrayAsInterface3 返回。

    要修复案例 2,请尽可能长时间使用静态类型的变量,因为它更安全(捕获错误)和更高效。

    func ReturnArrayAsInterface2() (retval interface{}) {
        defer func() {
            if r := recover(); r != nil {
                retval = r
            }
        }()
        r := make([]int, 0)
        retval = append(r, 4, 6, 8, 10)
        return
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-22
      • 2017-01-25
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多