为了账号安全,请及时绑定邮箱和手机立即绑定

Go 类型开关中的代码重复

Go 类型开关中的代码重复

Go
九州编程 2021-06-22 17:57:27
刚刚开始编写 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 时,对于这种事情,有什么更好的习惯用法?
查看完整描述

2 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

您的示例不是惯用的 Go 代码,尽管惯用的代码在词汇上似乎也违反了 DRY 原则。


理解的关键点是 'x'在每种类型的情况下都是一个单独的、不同类型的变量:


function(someArr interface{}){

        switch x := someArr.(type) {

        case []int:

                for i := range x {

                        // CODE

                }

        case []string:

                for i := range x {

                        // CODE

                }

        }

}


查看完整回答
反对 回复 2021-06-28
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

您可以使用反射包来迭代任意切片。但是[]int显式地实现特殊情况(如)通常更快,并且通常除了避免在常见情况下的反射之外还这样做。


package main


import "fmt"

import "reflect"


func foo(values interface{}) {

    rv := reflect.ValueOf(values)

    if rv.Kind() != reflect.Slice {

        return

    }

    n := rv.Len()

    for i := 0; i < n; i++ {

        value := rv.Index(i).Interface()

        fmt.Println(value)

    }

}


func main() {

    foo([]int{1, 3, 3, 7})

}

编辑:我不确定为什么有人对这个问题和我的答案投了反对票,但在某些情况下,您需要处理这样的代码。甚至标准库也包含很多,例如“fmt”、“gob”、“json”、“xml”和“template”。提问者可能面临类似的问题。


查看完整回答
反对 回复 2021-06-28
  • 2 回答
  • 0 关注
  • 167 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信