2015-10-10 2 views
0

Я хочу написать функцию, которая может преобразовать slice ([] int, [] string, [] bool, [] int64, [] float64) в строку.golang - как получить элемент из интерфейса {} тип среза?

[]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 
} 

ответ

0

Вы не можете этого сделать, потому что фрагмент 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, но по дороге вы потеряете много удобства для вызывающего абонента.

Смежные вопросы