内置函数"append"的工作原理:附加到其元素为interface类型的切片

use*_*291 0 go

附加到规范上的切片的部分提到了以下示例:

var t []interface{}
t = append(t, 42, 3.1415, "foo")   // t == []interface{}{42, 3.1415, "foo"}
Run Code Online (Sandbox Code Playgroud)

我在这里很困惑,为什么我们可以追加它们的元素的值int,float并且string它们slice的元素interface类型是什么?为什么这样的结果append呢?我努力/长期努力,但我没有得到它.

小智 5

因为:

所有类型都实现空接口

有关详细信息,请阅读接口参考规范.

interface类似于Objectjava中所有类型/类/等也是一个Object.

您可以使用reflect以下方法查看此效果:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var t []interface{}
    z := append(t, "asdf", 1, 2.0)
    fmt.Println(z)

    for i := range z {
        fmt.Println(reflect.TypeOf(z[i]))
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

[asdf 1 2]
string
int
float64
Run Code Online (Sandbox Code Playgroud)

为什么会这样?好吧,想想特别是JSON对象的序列化; 类型可以是字符串,整数,对象等.这允许反序列化而不指定完全映射的结构(可能你不关心,只想要一些数据等).基本上,它允许你在Go中有一种"弱打字"的形式; 虽然仍然能够打字很强.

如下所述,reflect为您确定类型.编程时,您可能需要手动编程.

  • 我认为值得一提的是,"附加结果"并不是你看到的印刷品.这只是字符串表示,它断言实际值的基础类型!如果没有进行那种类型的断言,那么切片看起来就像`[interface {} interface {} interface {}]` (2认同)