Bicep 中的数据类型

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

任意

对于 Bicep 版本 v0.38.3 及更高版本,Bicep 中的类型是一种宽松类型, any 用于禁用对关联符号的编译时类型检查。 类型的 any 值可以保存任何类型的数据,包括 stringintboolarrayobject复杂表达式。

param foo any
output bar any = foo

在前面的示例中, foo 可以接受任何类型的值,并 bar 输出与其类型无关的值 foo

由于 any 绕过 Bicep 的类型安全性,因此仅当无法提前确定确切类型时,才应使用该类型。 例如,在通过处理多个数据形状的模块传递数据或处理非类型化 JSON 输入时。

使用 any 可降低 Bicep 的可预测性,并可能导致运行时错误。 如果可能,首选特定类型或预期类型的联合,以保留验证和 IntelliSense 支持。 No explicit Any linter 规则有助于识别并阻止在 Bicep 文件中使用该any类型。

数组

Bicep 中的 数组 是值的有序集合,例如字符串、整数、对象,甚至其他数组,通常用于对相关项(如资源名称、配置设置或参数)进行分组。 数组有助于组织部署数据、将列表传递给资源以及循环访问多个值。

Bicep 中的数组是不可变的。 声明后,无法更改其内容。 若要“修改”数组,请使用函数(或concatmapfilter)创建新数组。

可以使用单行或多行语法在 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'
]

var arrayOfObjects = [
  { name: 'dev', size: 1 }
  { name: 'prod', size: 2 }
]

Bicep 中的数组的下标从零开始。 可以按索引访问元素:

var exampleArray = [1, 2, 3]
output firstElement int = exampleArray[0] // 1
output thirdElement int = exampleArray[2] // 3

var index = 1
output secondElement int = exampleArray[index] // 2

Bicep CLI 版本 0.34.x 开始,可以使用 array[^index] 语法从数组末尾访问元素 - ^1 引用最后一个元素、 ^2 第二到最后一个元素等。

var exampleArray = [1, 2, 3]

output lastElement int = exampleArray[^1] // 3
output secondToLastElement int = exampleArray[^2] // 2

如果访问超出边界的索引,则会收到错误:

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 是字符串字面量类型。 只能将值 red 分配给 redColor

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 分析器按原样读取每个字符。 根据 Bicep 文件中的行尾,新行会被解释为 \r\n\n

多线串目前不支持内插。 由于这一限制,可能需要使用 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 中,联合类型允许创建由一组子类型组成的组合类型。 如果允许任何单独的子类型赋值,则赋值有效。 | 字符用于分隔使用 or 条件的各个子类型。 例如,语法 a | b 表示有效的赋值可以是 ab。 联合类型在 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)[]

联合类型必须可减少至单个 Azure 资源管理器类型,例如 stringintbool。 否则,会收到 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 资源管理器类型。 以下定义无效:

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

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

可以在用户定义的数据类型中使用联合类型语法。

可为 null 的类型

可以通过将任何 ? 基元或复杂类型追加到类型名称来使任何基元或复杂类型可为 null。 这样,参数、变量或输出就可以接受 null 作为有效值。 例如:

output description string? = null
output config object? = null
output optionalValue int? = null

安全字符串和对象

安全字符串使用与字符串相同的格式,安全对象使用与对象相同的格式。 在使用 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 文件结构和语法