То, что вы хотите, называется утверждение типа. http://golang.org/ref/spec#Type_assertions
Простой пример на этой странице:
var x interface{} = 7 // x has dynamic type int and value 7
i := x.(int) // i has type int and value 7`
Другая вещь, чтобы отметить, что утверждение типа возвращает значение, называемое ok
, что является истинным, если утверждение является успешным. Вот простой пример кода для вашего случая:
a := []interface{}{}
b := []interface{}{}
type S struct {
text string
}
s := S{"string"}
t := S{"string"}
a = append(a, s)
b = append(b, t)
a = append(a, b)
assertedS,ok := a[0].(S)
if !ok { // If this is, in fact, not a value of type S, something is wrong
// error handling
}
fmt.Println(assertedS) // Should show you the same thing as printing s
assertedB,ok := a[1].([]interface{})
if !ok {
//...
}
assertedT,ok := assertedB[0].(S)
if !ok {
//...
}
fmt.Println(assertedT) // Should show you the same thing as printing t
Если вы не знаете заранее, какой список элементов является то, что вы можете перемещаться по нему и использовать «тип переключателя». http://golang.org/ref/spec#Switch_statements
switch x.(type) {
// cases
}
Что позволяет выполнять условное поведение в зависимости от того, какой хранимая интерфейс {} на самом деле.
Например, вы можете использовать
func ExtractSlice(a []interface{}) {
for _,x := range a {
switch i := x.(type) {
case S:
fmt.Println(i)
case []interface{}:
ExtractSlice(i) // Recursively unpacks b once it's found within a
}
}
}
Речь идет об элементах среза. Как насчет ** элементов элементов **. Я предполагаю, что нам нужно «задуматься», но я не знаю, как это сделать? – jiyinyiyong