Go 类型开关中的代码重复

刚刚开始编写 Go 代码,我遇到了一个有趣的问题。


有没有一种方法可以轻松地遍历作为空接口引入的数组中的项目而无需重复代码?考虑以下:


function(someArr interface{}){

  switch someArr.(type){

    case []int :

        arr := (someArr).([]int)

        for i := range (arr) {

          // CODE

        }


    case []string :

        arr := (someArr).([]string)

        for i := range (arr) {

          // CODE

        }

  } 

}

在此示例中,CODE 中的代码完全相同。但是,我不能将它从 switch 中取出,因为类型断言 arr 会超出范围。同样,我无法在 switch 之前定义 arr,因为我不知道它将是什么类型。这可能是做不到的。在这种情况下,当我使用不规则模式(一些整数数组、一些数组或字符串)解析 JSON 时,对于这种事情,有什么更好的习惯用法?


九州编程
浏览 168回答 2
2回答

GCT1015

您的示例不是惯用的 Go 代码,尽管惯用的代码在词汇上似乎也违反了 DRY 原则。理解的关键点是 'x'在每种类型的情况下都是一个单独的、不同类型的变量:function(someArr interface{}){        switch x := someArr.(type) {        case []int:                for i := range x {                        // CODE                }        case []string:                for i := range x {                        // CODE                }        }}

至尊宝的传说

您可以使用反射包来迭代任意切片。但是[]int显式地实现特殊情况(如)通常更快,并且通常除了避免在常见情况下的反射之外还这样做。package mainimport "fmt"import "reflect"func foo(values interface{}) {&nbsp; &nbsp; rv := reflect.ValueOf(values)&nbsp; &nbsp; if rv.Kind() != reflect.Slice {&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; n := rv.Len()&nbsp; &nbsp; for i := 0; i < n; i++ {&nbsp; &nbsp; &nbsp; &nbsp; value := rv.Index(i).Interface()&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(value)&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; foo([]int{1, 3, 3, 7})}编辑:我不确定为什么有人对这个问题和我的答案投了反对票,但在某些情况下,您需要处理这样的代码。甚至标准库也包含很多,例如“fmt”、“gob”、“json”、“xml”和“template”。提问者可能面临类似的问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go