如何遍历结构体切片而不是切片的结构体。

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

How to range over slice of structs instead of struct of slices

问题

在使用Go HTML模板进行一些尝试后,我发现在模板中循环遍历对象的所有示例都是将切片的结构体传递给模板,就像这个例子中一样:

type UserList struct {
    Id   []int
    Name []string
}

var templates = template.Must(template.ParseFiles("main.html"))

func rootHandler(w http.ResponseWriter, r *http.Request) {
    users := UserList{
        Id:   []int{0, 1, 2, 3, 4, 5, 6, 7},
        Name: []string{"user0", "user1", "user2", "user3", "user4"},
    }
    templates.ExecuteTemplate(w, "main", &users)
}

其中"main"模板如下:

{{define "main"}}
    {{range .Name}}
        {{.}}
    {{end}}
{{end}}

这个方法是可行的,但是如果我只在.Name属性上进行循环遍历,我不明白如何将每个ID显示在其对应的Name旁边。我认为在显示时将每个用户视为一个对象以分组其属性更合理。

因此,我的问题是:

如果我想将一个结构体切片传递给模板,该怎么做? 如何编写语法使其工作?我在官方的html/template文档中没有找到或理解如何做到这一点。
我想象中的代码大致如下:

type User struct {
    Id   int
    Name string
}
type UserList []User
var myuserlist UserList = ...

模板大致如下(这里的语法是故意错误的,只是为了让人理解):

{{define "main"}}
    {{for each User from myuserlist as myuser}}
        {{myuser.Id}}
        {{myuser.Name}}
    {{end}}
{{end}}
英文:

Having played around with Go HTML templates a bit, all the examples I found for looping over objects in templates were passing structs of slices to the template, somewhat like in this example :

type UserList struct {
	Id   []int
	Name []string
}

var templates = template.Must(template.ParseFiles("main.html"))

func rootHandler(w http.ResponseWriter, r *http.Request) {
	users := UserList{
		Id:   []int{0, 1, 2, 3, 4, 5, 6, 7},
		Name: []string{"user0", "user1", "user2", "user3", "user4"},
	}
	templates.ExecuteTemplate(w, "main", &users)
}

with the "main" template being :

{{define "main"}}
    {{range .Name}}
        {{.}}
    {{end}}
{{end}}

This works, but i don't understand how I'm supposed to display each ID just next to its corresponding Name if i'm ranging on the .Name property only. I would find it more logical to treat each user as an object to group its properties when displaying.

Thus my question:

What if I wanted to pass a slice of structs to the template? What would be the syntax to make this work? I haven't found or understood how to in the official html/template doc.
I imagined something looking remotely like this:

type User struct {
	Id   int
	Name string
}
type UserList []User
var myuserlist UserList = ...

and a template looking somewhat like this: (syntax here is deliberately wrong, it's just to get understood)

{{define "main"}}
    {{for each User from myuserlist as myuser}}
        {{myuser.Id}}
        {{myuser.Name}}
    {{end}}
{{end}}

答案1

得分: 42

使用以下模板:

{{range .}}
    {{.Id}}
    {{.Name}}
{{end}}

这是一个示例:http://play.golang.org/p/A4BPJOcfpB
你需要阅读有关包概述中的“dot”部分,以了解如何正确使用它。http://golang.org/pkg/text/template/#pkg-overview(查看Pipelines部分)

英文:

Use:

{{range .}}
    {{.Id}}
    {{.Name}}
{{end}}

for the template.
Here is a example: http://play.golang.org/p/A4BPJOcfpB
You need to read more about the "dot" in the package overview to see how to properly use this. http://golang.org/pkg/text/template/#pkg-overview (checkout the Pipelines part)

答案2

得分: 2

我没有评论的权限,但是回答@ROMANIA_engineer的问题,elithrar引用的来源已经被删除了,对于仍在寻找这个参考资料的人来说:

这本书已经被删除,因为它将很快由APress出版。请参阅《使用Go进行网络编程:使用和保护网络的基本技能》

英文:

I don't have the rep to comment, but to answer @ROMANIA_engineer, the source cited by elithrar has been retired, for anyone still looking for this reference :

> This book has been removed as it will shortly be published by APress. Please see Network Programming with Go: Essential Skills for Using and Securing Networks

huangapple
  • 本文由 发表于 2014年7月3日 22:09:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/24556001.html
匿名

发表评论

匿名网友

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

确定