如何打印包含点的键的值

问题描述 投票:12回答:4

我正在尝试打印地图的值,其键上有一个点(.)。

示例地图:

type TemplateData struct {
    Data map[string] int
}
tpldata := TemplateData{map[string]int {"core.value": 1}}

我试过了:

{{ $key := "core.value" }}
{{ .Data.key }}

但得到了:

2014/06/17 16:46:17 http: panic serving [::1]:41395: template: template.html:13: bad character U+0024 '$'

{{ .Data."core.value" }}

但得到了:

2014/06/17 16:45:07 http: panic serving [::1]:41393: template: template.html:12: bad character U+0022 '"'

请注意,我能够成功打印没有点的键值。

templates go
4个回答
19
投票

正如@ martin-ghallager所说,人们需要使用外部函数来访问这些元素。

希望标准库已经提供了函数indexhttp://golang.org/pkg/text/template/#hdr-Functions),它将完全执行Martin的dotNotation函数。

要使用它只需写:

{{ index .Data "core.value" }}

如果密钥不存在,index函数将返回默认值。如果您的字典具有同类数据,则此方法有效,但是当它是异构数据时,它将返回错误的值。在这种情况下,您可以使用以下方式显式设置默认值:

{{ 0 | or (index .Data "core.value") }}

5
投票

正如fabrizioM所说的那样,它违背了软件包的规格,但是没有什么可以阻止你使用函数映射创建自己的访问器来使用点符号:

package main

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

type TemplateData struct {
    Data map[string]int
}

var funcMap = template.FuncMap{
    "dotNotation": dotNotation,
}

func main() {
    data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

    t, err := template.New("foo").Funcs(funcMap).Parse(`{{dotNotation .Data "core.value"}}`)

    if err != nil {
        fmt.Println(err)
    }

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

    if err != nil {
        fmt.Println(err)
    }
}

func dotNotation(m map[string]int, key string) int {
    // Obviously you'll need to validate existence / nil map
    return m[key]
}

http://play.golang.org/p/-rlKFx3Ayt


2
投票

不,你不能。根据http://golang.org/pkg/text/template/#Arguments的规格,关键必须是字母数字

- The name of a key of the data, which must be a map, preceded
  by a period, such as
    .Key
  The result is the map element value indexed by the key.
  Key invocations may be chained and combined with fields to any
  depth:
    .Field1.Key1.Field2.Key2
  Although the key must be an alphanumeric identifier, unlike with
  field names they do not need to start with an upper case letter.
  Keys can also be evaluated on variables, including chaining:
    $x.key1.key2

您仍然可以通过迭代Map包main来打印它

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

type TemplateData struct {
    Data map[string]int
}

func main() {
    data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

    t, err := template.New("foo").Parse(`{{range $key, $value := .Data}}
   {{$key}}: {{$value}}
{{end}}`)
    if err != nil {
        fmt.Println(err)
    }
    err = t.Execute(os.Stdout, data)
    if err != nil {
        fmt.Println(err)
    }
}

http://play.golang.org/p/6xB_7WQ-59


-1
投票

我有一个类似的问题,我在秘密金库中的关键名称中有-.,例如

test-keytest.key

如果这样解决了

    {{ with secret "secret/path/test"}}
       {{ range $k, $v := .Data }}
          {{ $k }}:{{ $v }}
          {{ end }}
    {{ end }}

希望这会帮助别人......

© www.soinside.com 2019 - 2024. All rights reserved.