golang - 如何从接口{}类型的切片中获取元素?

时间:2015-10-10 03:27:05

标签: go

我想编写一个可以将slice([] int,[] string,[] bool,[] int64,[] float64)转换为字符串的函数。

[]string{a,b,c} -> a,b,c
[]int{1,2,3}    -> 1,2,3

我的code

func sliceToString(itr interface{}) string {
    switch itr.(type) {
    case []string:
        return strings.Join(itr.([]string), ",")
    case []int:
        s := []string{}
        for _, v := range itr.([]int) {
            s = append(s, fmt.Sprintf("%v", v))
        }
        return strings.Join(s, ",")
    case []int64:
        s := []string{}
        for _, v := range itr.([]int64) {
            s = append(s, fmt.Sprintf("%v", v))
        }
        return strings.Join(s, ",")
    case []float64:
        s := []string{}
        for _, v := range itr.([]float64) {
            s = append(s, fmt.Sprintf("%v", v))
        }
        return strings.Join(s, ",")
    case []bool:
        s := []string{}
        for _, v := range itr.([]bool) {
            s = append(s, fmt.Sprintf("%v", v))
        }
        return strings.Join(s, ",")
    }

    return ""
}

但它有点复杂,如果我可以将接口{}(类型为切片)转换为[]接口{}或获取元素,它会变得更简单。

 func sliceToString(itr interface{}) string {
    s := []string{}
    // convert interface{} to []interface{} or get elements
    // els := ...
    for _,v:= range els{
       s = append(s, fmt.Sprintf("%v", v))
    }
    return s
 }

1 个答案:

答案 0 :(得分:1)

你不能这样做,因为一片int,string或者任何东西都不能直接转换成一片接口。 (有关此问题的更多解释,请参阅that question。)

要进行转换,您需要将切片的每个项目分别转换为interface{}。并且您无法在不首先转换为切片的情况下访问这些项目,但为此您需要知道切片的类型(因此我们重新回到原点)。

缩短语法的一种方法是接受一片接口作为参数,让调用者进行转换(因为调用者知道切片的类型)。以下是一个示例:https://play.golang.org/p/6yLYk1OM25

package main

import (
    "fmt"
    "strings"
)

func main() {
    mySlice := []int{1, 2, 3}

    interfaceSlice := make([]interface{}, len(mySlice))
    for index := range mySlice {
        interfaceSlice[index] = mySlice[index]
    }

    fmt.Println(sliceToString(interfaceSlice))
}

func sliceToString(values []interface{}) string {
    s := make([]string, len(values)) // Pre-allocate the right size
    for index := range values {
        s[index] = fmt.Sprintf("%v", values[index])
    }
    return strings.Join(s, ",")
}

这适用于mySlice的任何切片,但是在途中会给调用者带来很多便利。