Учитывая сценарий, в котором у вас есть функция, которая принимает t interface{}
. Если определено, что t
это срез, как мне пройти range
над этим срезом?
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)
}
}
}
Пример игровой площадки Go: http://play.golang.org/p/DNldAlNShB
go
reflection
slice
go-reflect
Нуклон
источник
источник
Ответы:
Хорошо, я использовал,
reflect.ValueOf
а затем, если это срез, вы можете вызватьLen()
иIndex()
по значению, чтобы получитьlen
срез и элемент по индексу. Я не думаю, что вы сможете использовать для этого управление диапазоном.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)) } } }
Пример игровой площадки Go: http://play.golang.org/p/gQhCTiwPAq
источник
s.Index(i)
возвращает a,reflect.Value
поэтому в моем случае мне нужноs.Index(i).Interface()
было ссылаться на фактическое значение.interface{}
? напримерmoredata := &[]int{1,2,3}
Elem()
для получения базового значения. напримерreflect.TypeOf(reflect.ValueOf(t).Elem().Interface()).Kind()
Вам не нужно использовать отражение, если вы знаете, каких типов ожидать. Вы можете использовать переключатель типа , например:
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) } } }
Проверьте код на детской площадке .
источник
array[:]
.есть одно исключение из поведения интерфейса {}, @ Джереми Уолл уже дал указатель. если переданные данные изначально определены как [] interface {}.
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) } } }
выход:
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]
попробуй это
источник