Golang中遍历包含多个切片的结构体失效问题

Golang中遍历包含多个切片的结构体失效问题 https://play.golang.org/p/sWmlzLWvF4q

在这个简单的应用中,我可以将 HeaderFooter 结构体数据发送到模板,但无法将 Chunks 结构体数据解析到模板中。

我希望在 HTML 表格中遍历 ChunkedData 和 Users。 只有 Header 和 Footer 正常工作。

取消第 44 行的注释显示,待分块的数据正在所有用户之间分配。

10 回复

我已经尝试过了,但它不起作用。

更多关于Golang中遍历包含多个切片的结构体失效问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这正是我一直以来所期望的。非常感谢。

抱歉,我误解了你的意思。我会尝试一下。

抱歉,我的说明中遗漏了一些部分。我原本想说的是:https://play.golang.org/p/06881_SHHYd

非常感谢。 如果我想在HTML表格中显示数据,除了li标签,我还可以使用哪些其他的HTML标签?

或者说,在HTML表格中显示数据最高效的方式是什么?

当您使用 {{range .Chunk}} 时,模板本质上是在尝试执行 for _, x := range d.Chunk,但您无法这样做,因为您只能对数组、映射或切片进行范围遍历。您可以改为对 d.Chunk.ChunkDatad.Chunk.ChunkId 和/或 d.Chunk.ChunkId 进行范围遍历,例如使用 {{range .Chunk.ChunkData}} 等。

感谢您的回复。 您能否复制整个代码并使用第二种方法编辑第89行

Header : {{.HF.Header}}
Footer : {{.HF.Footer}}
{{range $index, $chunk := .Chunk}}
    {{index .Chunk.ChunkId $index}} : {{index .Chunk.User $index}} : {{index .Chunk.ChunkedData $index}}
{{end}}

我想了解它是如何工作的。

简单的 {{range .Chunk}} 会从 .Chunk 中提取值,并改变 {{range}} 内操作的作用域,使得 . 现在指向这些值。当你添加变量时,{{range $index, $chunk := .Chunk}} 就像 for index, chunk := range d.Chunk 循环一样工作。现在你有了一个索引,就可以用它来索引 d.Chunk 内的其他切片。在 Go 的模板语法中,实现 d.Chunk.Users[index] 的方式是 {{index .Chunk.Users $index}}

你可以将类型定义修改为类似这样:

type Chunk struct {
    ChunkedData []string
    User string
    ChunkId int
}

type Chunks []Chunk

/// 包含 Chunks 结构体和 HeaderFooter 结构体的结构体。
/// 此结构体将传递给 HTML 模板
type Data struct {
	Chunks
	HF    HeaderFooter
}

这将允许你编写:

Header : {{.HF.Header}}
Footer : {{.HF.Footer}}
{{range .Chunks}}
    {{.ChunkId}} : {{.User}} : {{.ChunkedData}}
{{end}}

或者,如果你保持现有的类型,并且假设 ChunkedDataUsersChunkId 切片中的索引是相关的(即 d.Chunk.ChunkedData[5]d.Chunk.Users[5]d.Chunk.ChunkId[5] 等相关联),那么你可以将模板修改为:

Header : {{.HF.Header}}
Footer : {{.HF.Footer}}
{{range $index, $chunk := .Chunk}}
    {{index .Chunk.ChunkId $index}} : {{index .Chunk.User $index}} : {{index .Chunk.ChunkedData $index}}
{{end}}

问题出在模板中对嵌套切片结构的访问方式。你的 Chunks 字段是一个 []ChunkedData,而每个 ChunkedData 又包含 []User,但模板中直接使用 {{range .Chunks.Users}} 是错误的访问方式。

这是修正后的代码示例:

package main

import (
	"html/template"
	"log"
	"os"
)

type HeaderFooter struct {
	Header string
	Footer string
}

type User struct {
	Name string
	Age  int
}

type ChunkedData struct {
	Users []User
}

type Chunks struct {
	Chunks []ChunkedData
}

func main() {
	headerFooter := HeaderFooter{
		Header: "Header",
		Footer: "Footer",
	}

	users := []User{
		{Name: "John", Age: 30},
		{Name: "Jane", Age: 25},
		{Name: "Bob", Age: 35},
		{Name: "Alice", Age: 28},
	}

	// 分块逻辑
	var chunkedData []ChunkedData
	chunkSize := 2
	for i := 0; i < len(users); i += chunkSize {
		end := i + chunkSize
		if end > len(users) {
			end = len(users)
		}
		chunkedData = append(chunkedData, ChunkedData{
			Users: users[i:end],
		})
	}

	chunks := Chunks{
		Chunks: chunkedData,
	}

	// 创建组合结构体
	data := struct {
		HeaderFooter
		Chunks
	}{
		HeaderFooter: headerFooter,
		Chunks:       chunks,
	}

	tmpl := `
Header: {{.Header}}
Footer: {{.Footer}}

Chunks:
{{range $chunkIndex, $chunk := .Chunks.Chunks}}
Chunk {{$chunkIndex}}:
{{range $userIndex, $user := $chunk.Users}}  User {{$userIndex}}: {{$user.Name}} ({{$user.Age}})
{{end}}
{{end}}
`

	t := template.Must(template.New("test").Parse(tmpl))
	err := t.Execute(os.Stdout, data)
	if err != nil {
		log.Fatal(err)
	}
}

关键修正点:

  1. 模板中需要使用 {{range .Chunks.Chunks}} 来遍历 Chunks 结构体的 Chunks 字段
  2. 在内部循环中,通过 $chunk.Users 访问每个分块中的用户数据
  3. 使用变量 $chunkIndex$userIndex 可以获取当前迭代的索引

对于HTML表格,你可以这样写模板:

<table>
  <thead>
    <tr>
      <th>Chunk Index</th>
      <th>User Index</th>
      <th>Name</th>
      <th>Age</th>
    </tr>
  </thead>
  <tbody>
    {{range $chunkIndex, $chunk := .Chunks.Chunks}}
      {{range $userIndex, $user := $chunk.Users}}
      <tr>
        <td>{{$chunkIndex}}</td>
        <td>{{$userIndex}}</td>
        <td>{{$user.Name}}</td>
        <td>{{$user.Age}}</td>
      </tr>
      {{end}}
    {{end}}
  </tbody>
</table>

这样就能正确遍历嵌套的切片结构了。

回到顶部