英文:
Go Template get a variable dynamically
问题
我有一个看起来像这样的yml参数:
nodes: one, two
instanceMinOne: 1
instanceMaxOne: 2
instanceMinTwo: 4
instanceMaxTwo: 6
有没有办法使用go模板动态读取例如instanceMinOne,其中变量名由instanceMin
+ 来自节点列表的动态值组成?
类似于(这显然不起作用,只是给出我想要实现的想法):
{{- range $nodeName := (split .Parameters.nodes) }}
instance-min: {{ .Parameters.instanceMin$nodeName }}
instance-max: {{ .Parameters.instanceMan$nodeName }}
{{- end }}
英文:
I have yml parameters that look like
nodes: one, two
instanceMinOne: 1
instanceMaxOne: 2
instanceMinTwo: 4
instanceMaxTwo: 6
Is there a way with go templating to dynamically read for example instanceMinOne where the variable name is composed of instanceMin
+ the dynamic value coming from the nodes list ?
something like (this obviously doesn't work but just give the idea of what I'd like to achieve)
{{ - range $nodeName := (split .Parameters.nodes) } } } }
instance-min: {{ .Parameters.instanceMin$nodeName }}
instance-max: {{ .Parameters.instanceMan$nodeName }}
{{ - end }}
答案1
得分: 3
要实现你想要的结果,你需要解决两个任务:
- 字符串拼接
- 使用动态值进行索引
对于字符串拼接,你可以使用内置的 print
函数,例如:
{{ $key := print "instanceMin" $nodeName }}
对于索引,使用内置的 index
函数:
instance-min: {{ index $.Parameters $key }}
(注意:{{range}}
动作会改变当前的上下文,所以在其中需要使用 $
来引用循环外的变量。)
或者可以写成一行:
instance-min: {{ index $.Parameters (print "instanceMin" $nodeName) }}
以下是一个可运行的示例:
func main() {
t := template.Must(template.New("").Parse(src))
params := map[string]interface{}{
"Parameters": map[string]interface{}{
"nodes": []string{"One", "Two"},
"instanceMinOne": 1,
"instanceMaxOne": 2,
"instanceMinTwo": 4,
"instanceMaxTwo": 6,
},
}
if err := t.Execute(os.Stdout, params); err != nil {
panic(err)
}
}
const src = `{{- range $idx, $nodeName := .Parameters.nodes }}
instance-min: {{ index $.Parameters (print "instanceMin" $nodeName) }}
instance-max: {{ index $.Parameters (print "instanceMax" $nodeName) }}
{{- end }}`
运行结果如下(可以在 Go Playground 上尝试):
instance-min: 1
instance-max: 2
instance-min: 4
instance-max: 6
英文:
To achieve what you want, you have to solve 2 tasks:
- string concatenation
- indexing with a dynamic value
For concatenation you may use the builtin print
function, e.g.
{{ $key := print "instanceMin" $nodeName }}
For indexing, use the builtin index
function:
instance-min: {{ index $.Parameters $key }}
(Note: The {{range}}
action changes the dot, so inside it you need $
to reference outside of the loop variable.)
Or in one line:
instance-min: {{ index $.Parameters (print "instanceMin" $nodeName) }}
See a runnable demo:
func main() {
t := template.Must(template.New("").Parse(src))
params := map[string]any{
"Parameters": map[string]any{
"nodes": []string{"One", "Two"},
"instanceMinOne": 1,
"instanceMaxOne": 2,
"instanceMinTwo": 4,
"instanceMaxTwo": 6,
},
}
if err := t.Execute(os.Stdout, params); err != nil {
panic(err)
}
}
const src = `{{- range $idx, $nodeName := .Parameters.nodes }}
instance-min: {{ index $.Parameters (print "instanceMin" $nodeName) }}
instance-max: {{ index $.Parameters (print "instanceMax" $nodeName) }}
{{- end }}`
This will output (try it on the Go Playground):
instance-min: 1
instance-max: 2
instance-min: 4
instance-max: 6
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论