List 和 field 推导可以让我们迭代一个 可迭代的对象 ,然后生成新的 list 或 field。
可迭代的对象是已存在的 list 或 struct 的 field。
import"strings"band: { name: "Led Zeppelin"// List comprehension selfTitled: [ for i, I in _selfIndexAlbums {title: "\(name) \(I)"}]// nested list comprehension allAlbums: [for I in _selfIndexAlbums {title: "\(name) \(I)"},for N in _namedAlbums {title: "\(N)"}, ] Albums: {// Field comprehension for key, val in allAlbums {"\(strings.TrimSpace(val.title))": { pos: key artist: name title: strings.TrimSpace(val.title) titleLen: len(val.title) } } }// Hidden fields _selfIndexAlbums: ["", "II", "III", "IV"] _namedAlbums: ["Houses of the Holy","Physical Graffiti","Presence","In Through the Out Door","Coda", ]}
我们之前已经介绍过文件中的一些用法:
list 推导: [ for key, val in iterable { ... } ],可以不使用 key,只用 value。
field 推导:[ for key, val in iterable { ... }],我们调用内置的函数插入一个 field,注意要用双引号包裹。
字符串插入:"(<a cue expression)"`,这是基于 Swift 的字符串插入,而且当你想要兼容 JSON 时,这个是唯一的机制。
隐藏字段:_hidden: "I'm hidden" 以下划线开头,CUE 也有隐藏定义 (_#)
band:name:Led ZeppelinselfTitled:- title:'Led Zeppelin '- title:Led Zeppelin II- title:Led Zeppelin III- title:Led Zeppelin IVallAlbums:- title:'Led Zeppelin '- title:Led Zeppelin II- title:Led Zeppelin III- title:Led Zeppelin IV- title:Houses of the Holy- title:Physical Graffiti- title:Presence- title:In Through the Out Door- title:CodaAlbums:Led Zeppelin:pos:0artist:Led Zeppelintitle:Led ZeppelintitleLen:13Led Zeppelin II:pos:1artist:Led Zeppelintitle:Led Zeppelin IItitleLen:15Led Zeppelin III:pos:2artist:Led Zeppelintitle:Led Zeppelin IIItitleLen:16Led Zeppelin IV:pos:3artist:Led Zeppelintitle:Led Zeppelin IVtitleLen:15Houses of the Holy:pos:4artist:Led Zeppelintitle:Houses of the HolytitleLen:18Physical Graffiti:pos:5artist:Led Zeppelintitle:Physical GraffitititleLen:17Presence:pos:6artist:Led Zeppelintitle:PresencetitleLen:8In Through the Out Door:pos:7artist:Led Zeppelintitle:In Through the Out DoortitleLen:23Coda:pos:8artist:Led Zeppelintitle:CodatitleLen:4
连接符 和 默认值
我们已经知道如何在验证中使用连接符了,你也可以在生成 value 和配置的时候使用它们。
#labels: [string]: string#metadata: { name: string// we can explicitly prevent namespace by commenting it out and ensuring this definition is closed// namespace?: string labels: #labels annotations?: [string]: string}// require the following keys for labels#requiredLabels: #labels & { app: string env: string team: string}// for env, limit the choices and default to dev with '*'#defaultLabels: #requiredLabels & { env: *"dev"|"stg"|"prd"}// set concrete values to be reused#myLabels: #defaultLabels & { app: "cuetorials" team: "hofstadter"}// our Kubernetes definitions from before#Schema: #Deployment | #Service | #Ingress// Additionally apply our labels buildup to the resources#Schema: { metadata: #metadata & { labels: #myLabels }}#Deployment: { apiVersion: "apps/v1" kind: "Deployment" ...}#Service: { apiVersion: "v1" kind: "Service" ...}#Ingress: { apiVersion: "extensions/v1beta1" kind: "Ingress" ...}
条件守卫
CUE 有个 if 声明,被称为 守卫 ,用于保护某个代码区块。
这不是条件分支,而是包含或者排除某些 CUE 代码的一种方法,
回想一下,CUE 是 图灵非完备 的,因此没有循环或条件分支的概念。
guards.cue
// use if guard to get even numbers in a list comprehensionnums: [1, 2, 3, 4, 5, 6, 7, 8]sqrs: [ for n in nums ifmod(n, 2) ==0 {n * n}]// use if guard to conditionally add fieldselems: [ {name: "a", public: true}, {name: "b", public: true}, {name: "c", public: false}, {name: "d"},]Elems: { hasPublicField: {for key, val in elems {// test against _|_ to see if a field existsif val.public !=_|_ {"\(key)": val } } } stringifyPublic: {for key, val in elems {// there is no short-circuit, so we must nest guard insteadif val.public !=_|_ {// test conjunctions not equal to bottom for "truthiness"if (val.public &true) !=_|_ {"\(key)": val & {PUB: "true"} }// note, there is no "else" clauseif (val.public &false) !=_|_ {"\(key)": val & {PUB: "false"} } } } }}