Golang移除接口类型切片中的nil元素

6
什么是从包含“nil”的interface{}切片中删除“nil”并生成新的interface{}切片的最佳方法?
 Slice := []interface{}{1, nil, "string", nil}

我不知道具体需要翻译的内容是什么,但是这句话的意思是“我脑海中没有好主意”。

我使用循环遍历范围并检查是否为空。 - James Sapam
你尝试了什么?请附上你的代码。你遇到了什么问题? - undefined
3个回答

8
newSlice := make([]interface{}, 0, len(Slice))
for _, item := range Slice {
    if item != nil {
        newSlice = append(newSlice, item)
    }
}

啊,我的问题是在执行make()时缺少了那个0。 - James Sapam
1
@James,make([]interface {},0)的效果是完全相同的,只是预分配了cap。在大多数情况下,我可能会只使用var newSlice []interface{},并让附加程序根据需要进行分配,因为这很少有影响。 - JimB
1
另外,如果顺序无关紧要,则可以进行原地过滤:https://play.golang.org/p/IWBeCs4Cwu - JimB
1
并且为了彻底性,在原地过滤器中保持顺序:https://play.golang.org/p/HUmUwYAMRq - JimB

3

除非有其他原因需要,否则可以在不分配新片的情况下完成此操作:

    things := []interface{}{
        nil,
        1,
        nil,
        "2",
        nil,
        3,
        nil,
    }

    for i := 0; i < len(things); {
        if things[i] != nil {
            i++
            continue
        }

        if i < len(things)-1 {
            copy(things[i:], things[i+1:])
        }

        things[len(things)-1] = nil
        things = things[:len(things)-1]
    }

    fmt.Printf("%#v", things)

输出:

[]interface {}{1, "2", 3}

您可以在此处玩耍,并且您可以在此处查找有关切片操作的更多信息


1

你也可以像这个例子一样使用类型开关:

slice := []interface{}{1, nil, "string", nil}
newSlice := make([]interface{}, 0, len(slice))

for _, val := range(slice){
    switch val.(type) {
        case string, int: // add your desired types which will fill newSlice
            newSlice = append(newSlice, val)
    }
}

fmt.Printf("newSlice: %v\tType: %T\n", newSlice, newSlice)

输出:

newSlice: [1 string]    Type: []interface {}

你可以在Go Playground中查看完整示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接