Mengingat skenario di mana Anda memiliki fungsi yang menerima t interface{}
. Jika ditentukan bahwa t
adalah irisan, bagaimana cara range
mengatasinya?
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)
}
}
}
Contoh Go Playground: http://play.golang.org/p/DNldAlNShB
go
reflection
slice
go-reflect
Nukleon
sumber
sumber
Jawaban:
Saya menggunakan
reflect.ValueOf
dan kemudian jika itu adalah irisan yang dapat Anda panggilLen()
danIndex()
nilai untuk mendapatkanlen
potongan dan elemen pada indeks. Saya tidak berpikir Anda akan dapat menggunakan jangkauan operasi untuk melakukan ini.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)) } } }
Contoh Go Playground: http://play.golang.org/p/gQhCTiwPAq
sumber
s.Index(i)
mengembalikanreflect.Value
jadi dalam kasus saya, saya perlus.Index(i).Interface()
mereferensikan nilai sebenarnya.interface{}
? misalnyamoredata := &[]int{1,2,3}
Elem()
untuk mendapatkan nilai yang mendasarinya. misalnyareflect.TypeOf(reflect.ValueOf(t).Elem().Interface()).Kind()
Anda tidak perlu menggunakan refleksi jika Anda tahu tipe mana yang diharapkan. Anda dapat menggunakan sakelar tipe , seperti ini:
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) } } }
Lihat kode di taman bermain .
sumber
array[:]
.ada satu pengecualian dari cara antarmuka {} berperilaku, @Jeremy Wall sudah memberikan pointer. jika data yang diteruskan awalnya didefinisikan sebagai [] antarmuka {}.
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) } } }
keluaran:
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]
mencobanya
sumber