【问题标题】:How to create an array of struct arrays of different types?如何创建不同类型的结构数组?
【发布时间】:2015-11-30 14:59:09
【问题描述】:

在我的程序中,我得到了 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

我做错了什么?

【问题讨论】:

  • 这无法完成。 Go 是静态类型的。重新设计您的解决方案。
  • 您无法将任何切片转换为[]interface{}。有关解释和解决方案,请参阅Type converting slices of interfaces in go
  • @Volker,icza 谢谢大家。
  • @WhiteAngel “go way”正在使用接口,我发布了一个可能有帮助的解决方案:)

标签: struct go slice


【解决方案1】:

您应该使用[]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

上试试

【讨论】:

  • 感谢您的回复。但这是我试图避免的——switch 语句和检查类型。在这种情况下,我将有重复的块,它们将为每种类型做完全相同的事情。那么,Go 不允许您以干净的方式执行此操作吗?对我来说,问题是我可能有 10 种不同的模型,甚至更多。
  • 也许您可以为此使用接口?
  • @RoninDev 喜欢我的回答吗?
  • @PabloFernandez 完全正确
【解决方案2】:

也许我没有得到你的要求,但是有什么问题

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

【讨论】:

    【解决方案3】:

    如何使用接口来解决您的问题?您甚至可以使用默认的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

    【讨论】:

      猜你喜欢
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多