go - 如何将多维 slice []接口(interface){}转换为 slice []字符串?

标签 go slice converters

示例来源:

// source multidimensional slice
var source = []interface{}{
    "value1",
    "value2",
    1234,
    1234.1234,
    []int{222, 333},
    []float32{444.444, 555.555},
    []interface{}{555, "value4", []int{777, 888}}
}

目标:

// target []string
var target = []string{
    "value1",
    "value2",
    "1234",
    "1234.1234",
    "222",
    "333",
    "444.444",
    "555.555",
    "555",
    "value4",
    "777",
    "888"
}

我写了转换函数。但这在我看来很麻烦,并且没有涵盖所有可能的选择。你能告诉我可以有更优雅的决定吗?

// convert multidimensional slice []interface{} to slice []string
func convert(raw interface{}) (result []string) {
    switch raw.(type) {
    case []string:
        result = append(result, raw.([]string) ...)
    case []int:
        for _, elem := range raw.([]int) {
            result = append(result, convert(elem) ...)
        }
    case string, int, int8, int16, int32, int64, float32, float64, complex64, complex128:
        result = append(result, fmt.Sprintf("%v", raw))
    case []float32:
        for _, elem := range raw.([]float32) {
            result = append(result, convert(elem) ...)
        }
    case []rune:
        for _, elem := range raw.([]rune) {
            result = append(result, convert(elem) ...)
        }
    case []int8:
        for _, elem := range raw.([]int8) {
            result = append(result, convert(elem) ...)
        }
    case []int16:
        for _, elem := range raw.([]int16) {
            result = append(result, convert(elem) ...)
        }
    case []int64:
        for _, elem := range raw.([]int64) {
            result = append(result, convert(elem) ...)
        }
    case []float64:
        for _, elem := range raw.([]float64) {
            result = append(result, convert(elem) ...)
        }
    case []complex64:
        for _, elem := range raw.([]complex64) {
            result = append(result, convert(elem) ...)
        }
    case []complex128:
        for _, elem := range raw.([]complex128) {
            result = append(result, convert(elem) ...)
        }
    case []interface{}:
        for _, elem := range raw.([]interface{}) {
            result = append(result, convert(elem) ...)
        }
    case [][]interface{}:
        for _, elem := range raw.([][]interface{}) {
            result = append(result, convert(elem) ...)
        }
    default:
        fmt.Println(fmt.Sprintf("Unknown type %v", raw))
        os.Exit(1)
    }
    return result
}

最佳答案

使用 reflect 包在几行代码中处理所有类型的 slice :

func convert(dst []string, v reflect.Value) []string {
    // Drill down to the concrete value
    for v.Kind() == reflect.Interface {
        v = v.Elem()
    }

    if v.Kind() == reflect.Slice {
        // Convert each element of the slice.
        for i := 0; i < v.Len(); i++ {
            dst = convert(dst, v.Index(i))
        }
    } else {
        // Convert value to string and append to result.
        dst = append(dst, fmt.Sprint(v.Interface()))
    }
    return dst
}

这样调用它:

stringSlice := convert(nil, reflect.ValueOf(source))

Run it on the Playground

关于go - 如何将多维 slice []接口(interface){}转换为 slice []字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54301251/

相关文章:

go - gc如何处理slice内存回收

string - 使用 JSF 转换器输出时将 null 或空字符串替换为指定值

pointers - 将结构成员作为指针是否很常见?

image-processing - 去调整图像大小

go - 如何访问gohtml中 slice 结构内的结构元素?

video - 拍摄实时视频流并将图像分成三份进行广播的最佳方式?

ruby - 将基于字符串的分钟和秒值相加

javascript - 将非 ASCII 字符(元音变音、重音符号...)转换为其最接近的 ASCII 等效字符(用于创建 slug)

go - golang 是否有一个用于下载第三方包的中央存储库?

Golang 返回零