Dado el escenario en el que tiene una función que acepta t interface{}
. Si se determina que t
es una rebanada, ¿cómo puedo range
superar esa rebanada?
func main() {
data := []string{"one","two","three"}
test(data)
moredata := []int{1,2,3}
test(data)
}
func test(t interface{}) {
switch reflect.TypeOf(t).Kind() {
case reflect.Slice:
// how do I iterate here?
for _,value := range t {
fmt.Println(value)
}
}
}
Ejemplo de Go Playground: http://play.golang.org/p/DNldAlNShB
go
reflection
slice
go-reflect
Nucleón
fuente
fuente
Respuestas:
Bueno, usé
reflect.ValueOf
y luego, si es un segmento, puede llamarLen()
yIndex()
en el valor para obtenerlen
el segmento y el elemento en un índice. No creo que pueda usar el rango de operación para hacer esto.package main import "fmt" import "reflect" func main() { data := []string{"one","two","three"} test(data) moredata := []int{1,2,3} test(moredata) } func test(t interface{}) { switch reflect.TypeOf(t).Kind() { case reflect.Slice: s := reflect.ValueOf(t) for i := 0; i < s.Len(); i++ { fmt.Println(s.Index(i)) } } }
Ejemplo de Go Playground: http://play.golang.org/p/gQhCTiwPAq
fuente
s.Index(i)
devuelva un,reflect.Value
por lo que en mi caso necesitabas.Index(i).Interface()
hacer referencia al valor real.interface{}
? Por ejemplomoredata := &[]int{1,2,3}
Elem()
para obtener el valor subyacente. preflect.TypeOf(reflect.ValueOf(t).Elem().Interface()).Kind()
No necesita utilizar la reflexión si sabe qué tipos esperar. Puede usar un interruptor de tipo , como este:
package main import "fmt" func main() { loop([]string{"one", "two", "three"}) loop([]int{1, 2, 3}) } func loop(t interface{}) { switch t := t.(type) { case []string: for _, value := range t { fmt.Println(value) } case []int: for _, value := range t { fmt.Println(value) } } }
Mira el código en el patio de recreo .
fuente
array[:]
.hay una excepción en la forma en que se comporta la interfaz {}, @Jeremy Wall ya dio un puntero. si los datos pasados se definen como [] interfaz {} inicialmente.
package main import ( "fmt" ) type interfaceSliceType []interface{} var interfaceAsSlice interfaceSliceType func main() { loop(append(interfaceAsSlice, 1, 2, 3)) loop(append(interfaceAsSlice, "1", "2", "3")) // or loop([]interface{}{[]string{"1"}, []string{"2"}, []string{"3"}}) fmt.Println("------------------") // and of course one such slice can hold any type loop(interfaceSliceType{"string", 999, map[int]string{3: "three"}}) } func loop(slice []interface{}) { for _, elem := range slice { switch elemTyped := elem.(type) { case int: fmt.Println("int:", elemTyped) case string: fmt.Println("string:", elemTyped) case []string: fmt.Println("[]string:", elemTyped) case interface{}: fmt.Println("map:", elemTyped) } } }
salida:
int: 1 int: 2 int: 3 string: 1 string: 2 string: 3 []string: [1] []string: [2] []string: [3] ------------------ string: string int: 999 map: map[3:three]
Pruébalo
fuente