Bicep 中的数据类型

本文介绍 Bicep 中支持的数据类型。 若要定义自定义数据类型,请参阅 用户定义的数据类型

支持的类型

在 Bicep 中,可使用以下数据类型:

数组

数组以左中括号 ([) 开头,以右中括号 (]) 结尾。 在 Bicep 中,可以在一行中或多行中声明数组。 在单行声明的值之间使用逗号 (,),但在多行声明中不使用,可以混合和匹配单行声明和多行声明。 多行声明需要 Bicep CLI 版本 0.7.X 或更高版本

var multiLineArray = [
  'abc'
  'def'
  'ghi'
]

var singleLineArray = ['abc', 'def', 'ghi']

var mixedArray = ['abc', 'def'
    'ghi']

每个数组元素可以是任何类型。 可具有其每个项的数据类型都相同的数组,也可具有包含不同数据类型的数组。

下面的示例演示一个整数数组和一个不同类型的数组。

var integerArray = [
  1
  2
  3
]

var mixedArray = [
  resourceGroup().name
  1
  true
  'example string'
]

Bicep 中的数组的下标从零开始。 在下面的示例中,表达式 exampleArray[0] 的计算结果为 1,exampleArray[2] 的计算结果为 3。 索引器的索引可以是另一个表达式。 表达式 exampleArray[index] 的计算结果为 2。 只允许对数组类型的表达式使用整数索引器。

var index = 1

var exampleArray = [
  1
  2
  3
]

当索引超出范围时,会出现以下错误:

The language expression property array index 'x' is out of bounds

若要避免此异常,可以使用 Or 逻辑运算符,如下例所示:

param emptyArray array = []
param numberArray array = [1, 2, 3]

output foo bool = empty(emptyArray) || emptyArray[0] == 'bar'
output bar bool = length(numberArray) <= 3 || numberArray[3] == 4

布尔型

指定布尔值时,请使用 truefalse。 不要将值用引号括起。

param exampleBool bool = true

整数

指定整数值时,请勿使用引号。

param exampleInt int = 1

Bicep 整数为 64 位整数。 作为内联参数传递时,值的范围可能受用于部署的 SDK 或命令行工具的限制。 例如,使用 PowerShell 部署 Bicep 时,整数类型的范围可能为 -2147483648 到 2147483647。 为了避免此限制,请在参数文件中指定大的整数值。 资源类型会针对整数属性应用其自己的限制。

Bicep 支持整数字面量类型,该类型是指具体的、精确的整数值。 在下面的示例中,1 是整数字面量类型,foo 只能赋值 1,不能赋其他值

output foo 1 = 1

整数字面量类型可以是内联声明的,如前面的示例所示,也可以在 type 语句中声明。

type oneType = 1

output foo oneType = 1
output bar oneType = 2

在前面的示例中,将 2 赋值给 bar 会导致 BCP033 错误 - 预期值的类型为“1”,但提供的值的类型为“2”

以下示例演示如何将整数字面量类型与联合类型结合使用:

output bar 1 | 2 | 3 = 3

目前不支持浮点、十进制或二进制格式。

对象

对象以左大括号 ({) 开头,以右大括号 (}) 结尾。 在 Bicep 中,可以在单行中或多行中声明对象。 对象中的每个属性都包含键和值。 键和值用冒号 (:) 分隔。 对象允许任何类型的任何属性。 在单行声明的属性之间使用逗号 (,),但在多行声明的属性之间不使用。 可以混合和匹配单行和多行声明。 多行声明需要 Bicep CLI 版本 0.7.X 或更高版本

param singleLineObject object = {name: 'test name', id: '123-abc', isCurrent: true, tier: 1}

param multiLineObject object = {
  name: 'test name'
  id: '123-abc'
  isCurrent: true
  tier: 1
}

param mixedObject object = {name: 'test name', id: '123-abc', isCurrent: true
    tier: 1}

在 Bicep 中,对象属性键可以有选择地使用引号:

var test = {
  'my - special. key': 'value'
}

在上一示例中,当对象属性键包含特殊字符时,使用了引号。 例如空格、'-' 或 '.'。 以下示例演示了如何在对象属性键中使用内插。

var stringVar = 'example value'
var objectVar = {
  '${stringVar}': 'this value'
}

属性访问器用于访问对象的属性。 它们是使用 . 运算符构造的。

var a = {
  b: 'Dev'
  c: 42
  d: {
    e: true
  }
}

output result1 string = a.b // returns 'Dev'
output result2 int = a.c // returns 42
output result3 bool = a.d.e // returns true

属性访问器可用于任何对象,包括对象类型和对象文字的参数和变量。 对非对象类型的表达式使用属性访问器是错误的。

还可以使用 [] 语法来访问属性。 下面的示例将返回 Development

var environmentSettings = {
  dev: {
    name: 'Development'
  }
  prod: {
    name: 'Production'
  }
}

output accessorResult string = environmentSettings['dev'].name

在 JSON 中,对象是零个或更多键/值对的无序集合。 排序可能会根据实现而有所不同。 例如,Bicep items() 函数按字母顺序对对象进行排序。 在其他位置,可以保留原始排序。 由于这种非确定性,在编写代码时避免对对象键排序做出任何假设,因为这会与部署参数和输出交互。

当访问不存在的对象属性时,将出现以下错误:

The language expression property 'foo' doesn't exist

若要避免此异常,可以使用 And 逻辑运算符,如下例所示:

param objectToTest object = {
  one: 1
  two: 2
  three: 3
}

output bar bool = contains(objectToTest, 'four') && objectToTest.four == 4

字符串

在 Bicep 中,字符串用单引号标记,并且必须在单行中声明。 允许使用码位在 010FFFF 之间的所有 Unicode 字符。

param exampleString string = 'test value'

下表列出了一组必须由反斜杠 (\) 字符转义的保留字符:

转义序列 表示的值 注释
\\ \
\' '
\n 换行 (LF)
\r 匹配回车符 (CR)
\t 制表符
\u{x} Unicode 码位 x x 表示 0(含)到 10FFFF(含)之间的十六进制码位值。 允许前导零。 高于 FFFF 的码位以代理项对的形式发出。
\$ $ 仅在后跟 { 时进行转义。
// evaluates to "what's up?"
var myVar = 'what\'s up?'

Bicep 支持字符串字面量类型,该类型是指具体的字符串值。 在下面的示例中,red 是字符串字面量类型,redColor 只能赋值 red,不能赋其他值

output redColor 'red' = 'red'

字符串字面量类型可以是内联声明的,如前面的示例所示,也可以在 type 语句中声明。

type redColor = 'red'

output colorRed redColor = 'red'
output colorBlue redColor = 'blue'

在前面的示例中,将 blue 赋值给 colorBlue 会导致 BCP033 错误 - 预期值的类型为“red”,但提供的值的类型为“blue”

以下示例演示如何将字符串字面量类型与联合类型结合使用:

type direction = 'north' | 'south' | 'east' | 'west'

output west direction = 'west'
output northWest direction = 'northwest'

Bicep 中的所有字符串都支持内插。 若要注入表达式,请将其括在 ${} 中。 引用的表达式不能跨多行显示。

var storageName = 'storage${uniqueString(resourceGroup().id)}'

多行字符串

在 Bicep 中定义多行字符串时,开头使用三个单引号字符 ('''),并且可以选择在其后跟随一个换行符(开始序列),结尾使用三个单引号字符(''' - 结束序列)。 在开始序列和结束序列之间输入的字符是逐字读取的,无需或不可能进行转义。

注意

由于 Bicep 分析程序按原样读取所有字符,因此换行符可解释为 \r\n\n,具体取决于 Bicep 文件的行尾。

多线串目前不支持内插。 由于此限制,可能需要使用 concat 函数,而不是使用内插

不支持包含 ''' 的多线串。

// evaluates to "hello!"
var myVar = '''hello!'''

// evaluates to "hello!" because the first newline is skipped
var myVar2 = '''
hello!'''

// evaluates to "hello!\n" because the final newline is included
var myVar3 = '''
hello!
'''

// evaluates to "  this\n    is\n      indented\n"
var myVar4 = '''
  this
    is
      indented
'''

// evaluates to "comments // are included\n/* because everything is read as-is */\n"
var myVar5 = '''
comments // are included
/* because everything is read as-is */
'''

// evaluates to "interpolation\nis ${blocked}"
// note ${blocked} is part of the string, and is not evaluated as an expression
var myVar6 = '''interpolation
is ${blocked}'''

联合类型

在 Bicep 中,联合类型允许创建由一组子类型组成的组合类型。 如果允许任何单独的子类型赋值,则赋值有效。 | 字符使用 条件分隔各个子类型。 例如,语法 'a' | 'b' 表示有效的赋值可以是 'a' 或 'b'。 联合类型在 Bicep 中被翻译为允许值约束,因此只有字面量可以作为成员。 联合可以包含任意数量的字面量类型表达式。

type color = 'Red' | 'Blue' | 'White'
type trueOrFalse = 'true' | 'false'
type permittedIntegers = 1 | 2 | 3
type oneOfSeveralObjects = {foo: 'bar'} | {fizz: 'buzz'} | {snap: 'crackle'}
type mixedTypeArray = ('fizz' | 42 | {an: 'object'} | null)[]

类型联合必须可简化为单种 ARM 类型,例如“string”、“int”或“bool”。 否则,会收到 BCP294 错误代码。 例如:

type foo = 'a' | 1

任何类型表达式都可以用作联合类型声明中的子类型(| 字符之间)。 例如,以下示例都是有效的:

type foo = 1 | 2
type bar = foo | 3
type baz = bar | (4 | 5) | 6

自定义标记联合数据类型

Bicep 支持自定义标记联合数据类型,该数据类型用于表示可以是多种不同类型之一的值。 若要声明自定义标记联合数据类型,可以使用 @discriminator() 修饰器。 需要安装 Bicep CLI 0.21.X 或更高版本才能使用此修饰器。 语法为:

@discriminator('<property-name>')

鉴别器装饰器采用单个参数,该参数表示所有联合成员之间的共享属性名称。 此属性名称必须是所有成员上必需的字符串文本,区分大小写。 联合成员上的可区分的属性的值必须是唯一的,并且采用不区分大小的方式。

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
param ServiceConfig  FooConfig | BarConfig | { type: 'baz', *: string } = { type: 'bar', value: true }

参数值根据可区分的属性值进行验证。 例如,在前面的示例中,如果 serviceConfig 参数的类型为 foo,则使用 FooConfig 类型对其进行验证。 同样,如果参数的类型为 bar,则使用 BarConfig 类型对其进行验证。 此模式也适用于其他类型。

联合类型存在一些限制。

  • 联合类型必须可减少至单个 Azure 资源管理器 (ARM) 类型。 以下定义无效:

    type foo = 'a' | 1
    
  • 仅允许字面量作为成员。

  • 所有字面量必须为相同的基元数据类型(例如,所有字符串或所有整数)。

联合类型语法可用于用户定义的数据类型

安全字符串和对象

安全字符串使用与字符串相同的格式,安全对象使用与对象相同的格式。 在使用 Bicep 时,请将 @secure()decorator 添加到字符串或对象。

将参数设置为安全字符串或安全对象时,参数的值不会保存到部署历史记录中,也不会记入日志。 但是,如果将该安全值设置为不应为安全值的属性,则该值不会受到保护。 例如,如果将安全字符串设置为标记,则该值将以纯文本的形式存储。 使用安全字符串作为密码和机密。

以下示例显示了两个安全参数:

@secure()
param password string

@secure()
param configValues object

数据类型可分配性

在 Bicep 中,可以将一个类型(源类型)的值分配给另一个类型(目标类型)。 下表显示哪个源类型(水平列出)可以或不可以分配给哪个目标类型(垂直列出)。 在表中,X 表示可分配,空白表示不可分配,? 表示仅当其类型兼容时才可分配。

类型 any error string number int bool null object array 命名资源 命名模块 scope
any X X X X X X X X X X X
error
string X X
number X X X
int X X
bool X X
null X X
object X X
array X X
resource X X
module X X
scope
命名资源 X
命名模块 X

后续步骤

若要了解 Bicep 的结构和语法,请参阅 Bicep 文件结构