go - 返回数组作为接口(interface)

标签 go types interface slice

案例一

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

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

案例2

考虑以下方法。这里我想在出现 panic 时返回错误,所以我在开头定义了 retval 并在 defer 中更改了它的值。但这显示错误“无法使用‘retval’(类型接口(interface){})作为类型 []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 是一种静态类型语言。您的第一个示例有效,因为 retval 的类型是 []int,因此您可以将 int 值附加到它。您使用了 short variable declaration ,所以 retval 的类型是从右侧表达式推断出来的,它显然是 []int 类型。当您返回此 []int 值时,它将自动包装在 interface{} 值中。

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

它将与 type assertion 一起工作:

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

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

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

关于go - 返回数组作为接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51243359/

相关文章:

go - 逃逸分析显示 channel 为泄漏参数

c# - 协变/逆变是否适用于不实现公共(public)接口(interface)的隐式可转换类型?

go - `Exit(1)` 到哪里,哪里返回错误?

go - 如何解析 DER 字节?

go - panic 与 log.Fatalln() 的结果有何不同?

haskell - 推断 lambda 表达式的类型

Haskell 约束族

Objective-C 类型推断

java - 为什么 Arrays.sort 采用 Object[] 而不是 Comparable[]?

java接口(interface)和新类