【问题标题】:How to call func on a Struct instance after storing in list存储在列表中后如何在 Struct 实例上调用 func
【发布时间】:2019-12-06 13:35:04
【问题描述】:

我尝试搜索,但找不到如何执行此操作。 我想获取我的结构的实例并将它们存储在一个列表中,然后遍历它们并在它们上调用一个函数。

type comicBook struct {
    Title     string
    Writer    string
    Artist    string
    Publisher string
    Year      int
    Pages     int
    Grade     float32
}
func (c comicBook) PrintInfo() {
    fmt.Println(c.Title, "written by", c.Writer, "drawn by", c.Artist, "published by", c.Publisher, "in", c.Year)
    fmt.Println("Pages:", c.Pages)
    fmt.Println("Grade:", c.Grade)
}

这很好用。

c := comicBook.NewComicBook(
        "Mr. GoToSleep",
        "Tracey Hatchet",
        "Jewel Tampson",
        "DizzyBooks Publishing Inc.",
        1997,
        14,
        6.5,
    )

c.PrintInfo()

c2 := comicBook.NewComicBook("Epic Vol. 1",
        "Ryan N. Shawn",
        "Phoebe Paperclips",
        "DizzyBooks Publishing Inc.",
        2013, 160, 9.0)

c2.PrintInfo()

将它们存储在列表中不会。

comicBookList := list.New()
    comicBookList.PushBack(c)
    comicBookList.PushBack(c2)

    fmt.Println("\nNow from a list!\n")

    for comic := comicBookList.Front(); comic != nil; comic = comic.Next() {
        comic.Value.PrintInfo()
    }

失败,comic.Value.PrintInfo undefined (type interface {} is interface with no methods)

【问题讨论】:

  • 你可能想查看这篇帖子stackoverflow.com/questions/18926303/…
  • 您使用的是什么列表类型?为什么要使用它而不是只使用切片?
  • @Adrian 我刚刚学习 Go,来自 C#。我曾期望 List 是一个基本容器,但我还不知道切片。 icza 给出的答案解决了我的问题。
  • 我建议从官方文档开始。以Tour of Go 为例,它涵盖了所有语言基础知识(包括切片)。另请阅读Effective Go,它涵盖了如何思考和编写好的 Go 代码的基础知识。

标签: list go struct func


【解决方案1】:

container/list 不是“通用的”,而是对interface{} 值进行操作。要从中获取“输入”值,您必须使用type assertion

for comic := comicBookList.Front(); comic != nil; comic = comic.Next() {
    comic.Value.(comicBook).PrintInfo()
}

Go Playground 上试试。

但你首先不应该使用container/list

改为使用slice。切片是通用的(在编译器的帮助下):

var books []comicBook

要向切片添加值,请使用内置的append()

b := comicBook.NewComicBook(...)
books = append(books, b)

要遍历切片,请使用 for range:

for _, b := range books {
    b.PrintInfo()
}

Go Playground 上试试。

【讨论】:

  • 谢谢。这比列表方法更有意义。
  • 我实际上在实现这一点时遇到了问题。 ComicBook 结构在另一个文件中(只是为了尝试管理导入),并且由于它的小写字母,它不会被导出。我尝试将其设为大写并执行 var comicBookList []comicBook.ComicBook 但在下一行出错,comicBook.ComicBook 没有字段或方法追加。
  • @galamdring append() 不是方法,而是函数。请再次检查您的使用方式:books = append(books, b)
【解决方案2】:

@icza 的回答是最好的方法。也就是说,您可以使用类型断言。

for comic := comicBookList.Front(); comic != nil; comic = comic.Next() {
    realComic, ok := comic.Value.(comicBook)
    if !ok {
        panic("this would error anyway, but good for visibility")
    }
    realComic.PrintInfo()
}

【讨论】:

    猜你喜欢
    • 2015-01-28
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多