Jsonnet顶层函数与数据能否同文件?如何简化嵌套JSON生成方案?
Jsonnet 嵌套仓库结构模板简化方案
问题概述
用Jsonnet自动生成包含场地、仓库、通道、货架等层级的嵌套模板化JSON结构,已实现模块化模板但存在以下问题:
- 需额外启动文件调用libsonnet模块;
- 属性名(如
"Warehouses")存在冗余;
尝试合并顶层函数与模板时出现解析报错,寻求简化实现方案。
现有实现代码
warehouses.libsonnet
{ warehouses (site, numWarehouses):: [ { SiteId: site, WarehouseId: site + '-' + y, } for y in std.range(1, numWarehouses) ], }
sites.libsonnet
local warehouses = import 'warehouses.libsonnet'; { sites (numSites,numLocations):: [ { SiteId: y, Warehouses: warehouses.warehouses(y,numLocations), } for y in std.range(1,numSites) ], }
warehouses.jsonnet
local warehouses = import 'warehouses.libsonnet'; function(s,n) { Warehouses: warehouses.warehouses(s,n) }
sites.jsonnet
local sites = import 'sites.libsonnet'; function(s,n) { Sites: sites.sites(s,n) }
简化方案
1. 消除冗余属性名,合并函数与模板
直接让模块文件返回函数,无需额外启动文件,同时去掉重复的外层属性名:
重构后的 warehouses.libsonnet
function(site, numWarehouses) [ { SiteId: site, WarehouseId: site + '-' + std.toString(y) } for y in std.range(1, numWarehouses) ]
重构后的 sites.libsonnet
local warehouses = import 'warehouses.libsonnet'; function(numSites, numLocations) [ { SiteId: std.toString(y), Warehouses: warehouses(y, numLocations) } for y in std.range(1, numSites) ]
2. 直接运行模块生成结果
现在可以直接调用这两个模块生成对应JSON,无需额外启动文件:
- 生成仓库列表:
jsonnet -A site=1 -A numWarehouses=3 warehouses.libsonnet - 生成场地列表:
jsonnet -A numSites=2 -A numLocations=3 sites.libsonnet
3. 若需保留顶层键名(可选)
如果需要像原代码那样带顶层Sites/Warehouses键,可在模块内直接包含,同时保留函数入口:
可选的 sites.libsonnet 写法
local warehouses = import 'warehouses.libsonnet'; function(numSites, numLocations) { Sites: [ { SiteId: std.toString(y), Warehouses: warehouses(y, numLocations) } for y in std.range(1, numSites) ] }
这样运行时直接调用模块即可,无需额外启动文件,同时避免了属性名冗余。
内容的提问来源于stack exchange,提问作者The F
相关产品推荐
相关产品推荐

