2013-12-16 1 views

ответ

4

То, что вы хотите, называется утверждение типа. 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 
    } 
    } 
} 
0

This code example может помочь:

package main 

import "fmt" 

func main() { 
    a := []interface{}{} 
    b := []interface{}{} 
    type S struct { 
     text string 
    } 

    s := S{"string s"} 
    t := S{"string t"} 
    a = append(a, s) 
    b = append(b, t) 
    a = append(a, b) 

    for _, v := range a { 
     fmt.Println(v) 
    } 
} 

, но быть в курсе, что вы определили a и b в качестве ломтиков интерфейсов. Это означает, что когда вы делаете a = append(a, b) вы помещаете ломтик b после существующего a строки в срезе a, и поэтому, когда вы range над a вы получите:

{строка} // ы интерфейс строки
[{строка т}] // кусок интерфейса строки

+0

Речь идет об элементах среза. Как насчет ** элементов элементов **. Я предполагаю, что нам нужно «задуматься», но я не знаю, как это сделать? – jiyinyiyong

2

ли вы имеете в виду это?

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) 
for _, v := range a { 
    switch v.(type) { 
    case S: 
     fmt.Println("S", v) 
    default: 
     fmt.Println("Slice", v) 
    } 
} 
Смежные вопросы