2015-09-04 103 views
2

在我的节目我有2种型号:如何创建不同类型的结构数组的数组?

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 

我在做什么错?

+1

这不能做。 Go是静态类型的。重新设计解决方案。 – Volker

+2

您无法将任何切片转换为'[] interface {}'。有关解释和解决方案,请参见[在接口中输入转换接口的切片](http://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go)。 – icza

+0

@Volker,icza谢谢,伙计们。 – WhiteAngel

回答

5

您应该使用的[]interface{}代替[][]interface{}
尝试它的go playground

如果你想要遍历所有的结构在你内心的数组,你需要将它们转换为正确的类型,然后重复,像这样的:

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

+1

感谢您的回复。但这正是我试图避免的 - “switch”语句和检查类型。在这种情况下,我会有重复的块,为每种类型做完全相同的事情。那么,Go不允许你以干净的方式做到这一点?对我来说,问题是我可能有10个不同的模型,甚至更多。 – WhiteAngel

+0

也许你可以使用它的接口? – RoninDev

+0

@RoninDev喜欢我的回答? –

0

如何使用接口解决您的问题?你甚至可以使用默认的fmt.Stringer接口,由fmt.Prtinf和其他标准方法使用。

例子:

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

游乐场:https://play.golang.org/p/W3qakrMfOd

1

也许我没有收到你的要求,但是这有什么错只是

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