在 GO 模板中使用 range over struct

我从中解析结构values.yaml并想在其中使用它template.yaml

这是我的values.yaml文件:

services:
  app:
    image: matryoshka/app
    replicaCount: 1
  cron:
    image: matryoshka/cron
    replicaCount: 1

这是我的template.yaml(无效代码):

{{- range $key, $value := .Services}}
    {{$key}}{{$value}}
{{- end}}

这给了我错误:

panic: template: template.yaml:1:26: executing "template.yaml" at <.Services>: range can't iterate over {{atryoshka/app 1} {matryoshka/cron 1}}

这是我的.go代码:

package main


import (

    "html/template"

    "io/ioutil"

    "os"

    "path/filepath"


    "gopkg.in/yaml.v2"

)


type Values struct {

    Services struct {

        App struct {

            Image        string `yaml:"image"`

            ReplicaCount string `yaml:"replicaCount"`

        } `yaml:"app"`

        Cron struct {

            Image        string `yaml:"image"`

            ReplicaCount string `yaml:"replicaCount"`

        } `yaml:"cron"`

    }

}


func parseValues() Values {


    var values Values

    filename, _ := filepath.Abs("./values.yaml")

    yamlFile, err := ioutil.ReadFile(filename)


    err = yaml.Unmarshal(yamlFile, &values)

    if err != nil {

        panic(err)

    }


    return values


}

func insertValues(class Values) {

    paths := []string{"template.yaml"}

    t, err := template.New(paths[0]).ParseFiles(paths...)

    if err != nil {

        panic(err)

    }

    err = t.Execute(os.Stdout, class)

    if err != nil {

        panic(err)

    }

}


func main() {

    values := parseValues()

    insertValues(values)

}

如何.Services正确迭代template.yaml?我发现只有选项,{{- range $key, $value := .Services}}但它不起作用。


慕的地6264312
浏览 146回答 1
1回答

函数式编程

正如您所经历的那样,您不能跨越结构的字段。您只能对切片、数组、映射和通道进行范围。使用地图最简单的方法就是传递它:一张地图。您可以直接将 YAML 解组为映射或空接口:func parseValues() interface{} {    var values interface{}    // ...rest is unchanged}func insertValues(class interface{}) {    // ...unchanged}稍微更改模板的格式(注意.services):{{- range $key, $value := .services}}{{$key}} {{$value}}{{- end}}有了这些,它就可以工作并且输出是:app map[replicaCount:1 image:matryoshka/app]cron map[image:matryoshka/cron replicaCount:1]使用切片如果您想继续使用您的Services模型,另一种选择是手动准备和传递一部分字段:insertValues([]interface{}{values.Services.App, values.Services.Cron})然后是模板:{{- range $key, $value := .}}{{$key}} {{$value}}{{- end}}然后是输出:0 {matryoshka/app 1}1 {matryoshka/cron 1}使用切片和反射如果您希望它保持“动态”(意味着您不必手动枚举字段),您可以创建一个辅助函数,它使用反射来实现。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go