drfu29983 2018-08-17 13:24
浏览 47
已采纳

如何仅使用1种方法删除不同类型的切片

I have 2 go functions like following

 func removeL2McEntry(a []api.L2McEntry, index int) []api.L2McEntry {
    a = append(a[:index], a[index+1:]...) 
    element
    return a[:len(a)]
 }

 func removeVlagBasedGroup(a []api.VlanPortBased, index int) []api.VlanPortBased {
    a = append(a[:index], a[index+1:]...) 
    return a[:len(a)]
 }

As you can see, both functions are doing the same work. But I need to separate them because the outputs and the inputs of the functions are different type.

I have tried:

func removeSlice(a interface{}, idx int) interface{} {
    switch v := a.(type) { 
    case []string:
        v = append(v[:idx], v[idx+1:]...) 
        fmt.Println("is ary", v)
        return v[:len(v)]
    case []int:
        v = append(v[:idx], v[idx+1:]...) 
        fmt.Println("is ary", v)
        return v[:len(v)]
    default:

    }
    return nil
}

But there is too many repetitive code in this way. Is there any way to make it just one function and reduce the repetitive code?

Thanks in advance.

  • 写回答

1条回答 默认 最新

  • dozc58418381 2018-08-17 13:41
    关注

    As Adrian noted, removing an element from a slice is one line of code, in general:

    a = append(a[:i], a[i+1]...)
    // or
    a = a[:i+copy(a[i:], a[i+1:])]
    

    It's not really worth writing a function for it, just use this code snippet where needed.

    If you do need to create a function that can handle any slice types, it can be created using reflection. But when using it, you will have to use a type assertion on the result, as the function can only return a static type of interface{}. It will also be slower than using the above snippet on your concrete slice value!

    The above remove steps can be "reproduced" using the reflect package. Slicing is the Value.Slice() method, and the append operation is the reflect.AppendSlice() function.

    This is how it could look like (types and bound checks omitted):

    func remove(s interface{}, i int) interface{} {
        v := reflect.ValueOf(s)
        return reflect.AppendSlice(v.Slice(0, i), v.Slice(i+1, v.Len())).Interface()
    }
    

    Testing it:

    is := []int{0, 1, 2, 3}
    is = remove(is, 2).([]int)
    fmt.Printf("%#v
    ", is)
    
    ss := []string{"0", "1", "2", "3"}
    ss = remove(ss, 2).([]string)
    fmt.Printf("%#v
    ", ss)
    

    Output (try it on the Go Playground):

    []int{0, 1, 3}
    []string{"0", "1", "3"}
    

    But again: I don't advise anyone to use this (although working) code, just remove the element directly with the original snippet.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决