简体   繁体   English

如何在Go中读取类似[] interface {}的片段?

[英]How to read an slice of like []interface{} in Go?

I have something like this: 我有这样的事情:

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)

a

And now I want to read elements of a, or elements of elements.. but how? 现在,我想读取a的元素,或元素的元素..但是如何?

What you want is called a type assertion. 您想要的称为类型断言。 http://golang.org/ref/spec#Type_assertions http://golang.org/ref/spec#Type_assertions

The simple example on that page is: 该页面上的简单示例是:

var x interface{} = 7  // x has dynamic type int and value 7
i := x.(int)           // i has type int and value 7`

The other thing to note is that a type assertion returns a value called ok that is true if the assertion is successful. 要注意的另一件事是类型断言返回一个称为ok的值,如果断言成功,则该值为true。 Here's a simple code example for your case: 这是适合您的情况的简单代码示例:

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

If you don't know ahead of time which list element is what, you can iterate through it and use the "type switch". 如果您不提前知道哪个列表元素是什么,则可以遍历该列表元素并使用“类型开关”。 http://golang.org/ref/spec#Switch_statements http://golang.org/ref/spec#Switch_statements

switch x.(type) {
    // cases
}

Which allows you to perform conditional behavior based on what type the stored interface{} really is. 它使您可以根据存储的接口{}的实际类型执行条件行为。

For instance, you might use 例如,您可以使用

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
    }
  }
}

Do you mean this? 你是这个意思吗

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)
    }
}

This code example may help: 此代码示例可能会帮助:

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)
    }
}

but be aware that you've defined a and b as slices of interfaces. 但请注意,您已将ab定义为接口的片段。 This means, that when you do a = append(a, b) you're putting the b slice after the existing a string in the a slice, and therefore when you range over a you get: 这意味着,当你做a = append(a, b)你把b现有的后片a在串a切片,因此,当你rangea你:

{string s} //interface of string {string s} //字符串接口
[{string t}] //slice of interface of string [{string t}] //字符串接口的切片

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM