我有一个像这样的模板:
"environment": [
{{- range $k,$v := .env }}
{
"name": "{{ $k }}",
"value": "{{ $v }}"
},
{{- end }}
]
我得到下面的输出:
"environment": [
{
"name": "name",
"value": "test"
},
{
"name": "region",
"value": "us-east-1"
},
]
我想渲染如下:
"environment": [
{
"name": "name",
"value": "bxbd"
},
{
"name": "region",
"value": "us-east-1"
}
]
我无法摆脱最后一个逗号来制作有效的json。还是可能以某种方式将完整的范围块发送到某些自定义联接功能?
这是一个如何使用模板的示例,但是如果要生成JSON,我强烈建议使用第二种方法。
由于您在地图上范围很广,因此您无法(简单地)做到这一点。如果是切片,则可以检查index变量(例如:Go模板除去range循环中的最后一个逗号;并使用go-
templates内的range检测数组中的最后一项
),但是对于maps则不能这样做。
知道您是否处于第一个(或最后一个)迭代 状态 是您必须维护自己的 状态 。例如,为此使用自定义函数或方法。
这是一个示例实现:
type Params struct {
Env map[string]string
Counter int
}
func (p *Params) IncMore() bool {
p.Counter++
return p.Counter < len(p.Env)
}
const src = `"environment": [
{{- range $k,$v := .Env }}
{
"name": "{{ $k }}",
"value": "{{ $v }}"
}{{if $.IncMore}},{{end}}
{{- end }}
]`
测试它:
func main() {
t := template.Must(template.New("").Parse(src))
p := &Params{
Env: map[string]string{
"name": "test",
"region": "us-east-1",
},
}
err := t.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
输出(在Go Playground上尝试):
"environment": [
{
"name": "name",
"value": "test"
},
{
"name": "region",
"value": "us-east-1"
}
]
encoding/json
产生JSON如果您的目标是生成JSON,则应使用该encoding/json
软件包生成有效的JSON文档。上面的模板不了解JSON语法和上下文,并且映射条目的值在写入输出时不会转义,因此您仍然可能得到无效的JSON。
最好是像这样生成JSON:
type Entry struct {
Name string `json:"name"`
Value string `json:"value"`
}
type Params struct {
Env []Entry `json:"environment"`
}
func main() {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ") // Optional
p := &Params{
Env: []Entry{
{Name: "name", Value: "test"},
{Name: "region", Value: "us-east-1"},
},
}
err := enc.Encode(p)
if err != nil {
panic(err)
}
}
输出(在Go Playground上尝试):
{
"environment": [
{
"name": "name",
"value": "test"
},
{
"name": "region",
"value": "us-east-1"
}
]
}
问题内容: 在包中的某个动作内,是否可以在range动作之前访问管道值,或者是否可以将父/全局管道作为参数传递给Execute? 工作示例显示了我尝试执行的操作: play.golang.org 问题答案: 使用$变量(推荐) 从软件包文本/模板文档中: 开始执行时,将$设置为传递给Execute的数据参数,即dot的起始值。 正如@Sandy所指出的,因此可以使用来访问外部作用域中的Path 。
问题内容: 在或中时,将更改的范围。您如何访问调用范围? 问题答案: 记录在文本/模板文档中: 开始执行时,将$设置为传递给Execute的数据参数,即dot的起始值。
问题内容: 给定模板: 这可以输出: 但是,如果我要输出: 我需要知道哪个是上述范围内的最后一个元素。 我可以设置一个变量,该变量保留数组的长度,但是始终为3,并且上面的值永远只能为2。而且,根据我所见,您无法在模板中执行算术运算。 是否可以检测模板范围内的最后一个值?干杯。 问题答案: 这可能不是最优雅的解决方案,但却是我能找到的最好的解决方案: http://play.golang.org/p
问题内容: 我的片结构,我的围棋程序,以保持名称和文件的大小。我创建了模板,如下所示: 我当然会慌张地说: 无法评估[] main.File类型的字段文件 不确定如何在模板中正确显示文件名和大小。 问题答案: 管道的初始值( 点 )是传递给您的值,在这种情况下,该值是type 。 因此,在模板执行期间, 点 是。该切片没有命名为模板中将引用的字段或方法的字段。 您应该做的就是简单地使用它,它指向您
Go 语言中 range 关键字用于for循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引值,在集合中返回 key-value 对的 key 值。 实例 package main import "fmt" func main() { //这是我们使用range去求一个slice的和。使用数组跟这个很类似
问题内容: 我正在学习语言,这些要点摘自的规范。 虽然我能理解分1-4,我很困惑的点和: 5. 在函数内部声明的常量或变量标识符的范围始于ConstSpec或VarSpec的末尾(对于简短变量声明为ShortVarDecl),并在最里面的包含块的末尾结束。 6. 在函数内部声明的类型标识符的范围始于TypeSpec中的标识符,并终止于最里面的包含块的末尾。 这是我用来了解Go范围的代码: 据此,我