如何创建一个包含不同类型的结构体数组的数组?

huangapple go评论108阅读模式
英文:

How to create an array of struct arrays of different types?

问题

在我的程序中,我有两个模型:

type User struct {
    Name string
}

type Article struct {
    Title string
}

我还有这些结构体的数据数组:

users := []User
articles := []Article

我试图在同一段代码中迭代它们:

models := [][]interface{} {users, articles}
for _, model := range models {
    log.Printf("%#v", model)
}

但是我收到了一个错误:

cannot use users (type []User) as type []interface {} in array element

我做错了什么?

英文:

In my program I got 2 models:

type User struct {
    Name string
}

type Article struct {
    Title string
}

And I got arrays of data of these structs:

users := []User
articles := []Article

I'm trying to iterate over both of them at the same piece of code:

models := [][]interface{} {users, articles}
for _, model := range models {
    log.Printf("%#v", model)
}

But I'm receiving an error:

cannot use users (type []User) as type []interface {} in array element

What am I doing wrong?

答案1

得分: 4

你应该使用[]interface{}而不是[][]interface{}。在你的内部数组中,如果你想迭代所有的结构体,你需要将它们转换为正确的类型,然后进行迭代,像这样:

for _, model := range models {
    if u, ok := model.([]User); ok {
        for _, innerUser := range u {
            log.Printf("%#v", innerUser)
        }
    }
    if a, ok := model.([]Article); ok {
        for _, innerArticle := range a {
            log.Printf("%#v", innerArticle)
        }
    }
}

你可以在go playground上尝试一下。

英文:

You should use []interface{} instead of [][]interface{}
Try it on the <kbd>go playground</kbd>

If you want to iterate all structs in your inner arrays, you need to cast them to the proper type and then iterate, like this:

for _, model := range models {
	if u, ok := model.([]User); ok {
		for _, innerUser := range u {
			log.Printf(&quot;%#v&quot;, innerUser)
		}
	}
	if a, ok := model.([]Article); ok {
		for _, innerArticle := range a {
			log.Printf(&quot;%#v&quot;, innerArticle)
		}
	}
}

Try it on the <kbd>go playground</kbd>

答案2

得分: 1

也许我没有理解你的要求,但是这段代码有什么问题呢?

models := []interface{} {users, articles}
for _, model := range models {
    log.Printf("%#v\n", model)
}

这段代码的作用是将usersarticles两个变量存储到一个切片中,并使用range循环遍历切片中的每个元素,然后使用log.Printf函数打印每个元素的值。

英文:

Maybe I'm not getting your requirements, but what's wrong with just

models := []interface{} {users, articles}
for _, model := range models {
    log.Printf(&quot;%#v\n&quot;, model)
}

答案3

得分: 0

使用接口来解决你的问题怎么样?你甚至可以使用默认的fmt.Stringer接口,它被fmt.Printf和其他标准方法使用。

示例代码:

package main

import "log"
import "fmt"

type User struct {
    Name string
}

type Article struct {
    Title string
}

func (art Article) String() string {
    return art.Title
}

func (user User) String() string {
    return user.Name
}

func main() {
    models := []interface{}{User{"user1"}, User{"user2"}, Article{"article1"}, Article{"article2"}}
    for _, model := range models {
        printable := model.(fmt.Stringer)
        log.Printf("%s\n", printable)
    }
}

Playground: https://play.golang.org/p/W3qakrMfOd

英文:

How about using interfaces to solve your problem? you can even use the default fmt.Stringer interface, used by fmt.Prtinf and other standard methods.

Example:

package main

import &quot;log&quot;
import &quot;fmt&quot;

type User struct {
	Name string
}

type Article struct {
	Title string
}

func (art Article) String() string {
	return art.Title
}

func (user User) String() string {
	return user.Name
}

func main() {
	models := []interface{}{User{&quot;user1&quot;}, User{&quot;user2&quot;}, Article{&quot;article1&quot;}, Article{&quot;article2&quot;}}
	for _, model := range models {
		printable := model.(fmt.Stringer)
		log.Printf(&quot;%s\n&quot;, printable)
	}
}

Playground: https://play.golang.org/p/W3qakrMfOd

huangapple
  • 本文由 发表于 2015年9月4日 20:36:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/32398263.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定