- OpenTofu 语言
- 表达式
- Splat 表达式
Splat 表达式
splat 表达式提供了一种更简洁的方式来表达一种常见的操作,否则可以用 for
表达式来执行。
如果 var.list
是一个包含具有 id
属性的所有对象的列表,则可以使用以下 for
表达式生成 id 列表
[for o in var.list : o.id]
这等效于以下splat 表达式:
var.list[*].id
特殊的 [*]
符号迭代其左侧给出的列表中的所有元素,并从每个元素中访问其右侧给出的属性名称。splat 表达式也可以通过将操作序列扩展到符号右侧来访问复杂类型列表的属性和索引
var.list[*].interfaces[0].name
上面的表达式等效于以下 for
表达式
[for o in var.list : o.interfaces[0].name]
带映射的 Splat 表达式
上面显示的 splat 表达式模式仅适用于列表、集合和元组。要使用映射或对象值获得类似的结果,必须使用 for
表达式.
使用 for_each
参数的资源将以对象映射的形式出现在表达式中,因此您不能对这些资源使用 splat 表达式。有关更多信息,请参见 引用资源实例.
单值作为列表
当您将 splat 表达式应用于不是列表、集合或元组的值时,它们具有特殊行为。
如果该值不是空值,则 splat 表达式将将其转换为单元素列表,更准确地说是单元素元组值。如果该值为null,则 splat 表达式将返回一个空元组。
这种特殊行为对于接受可选输入变量的模块很有用,这些变量的默认值为 null
,用于表示没有任何值。这允许模块为 OpenTofu 语言功能调整变量值,这些功能旨在与集合一起使用。例如
variable "website_setting" {
type = object({
index_document = string
error_document = string
})
default = null
}
resource "aws_s3_bucket" "example" {
# ...
dynamic "website" {
for_each = var.website_setting[*]
content {
index_document = website.value.index_document
error_document = website.value.error_document
}
}
}
上面的示例使用 dynamic
块,它根据集合值生成零个或多个嵌套块。输入变量 var.website_setting
被定义为可能为 null 的单个对象,因此 dynamic
块的 for_each
表达式使用 [*]
来确保如果模块调用者设置了网站参数,则将有一个块,如果调用者将其设置为 null,则为零个块。
splat 表达式的这种特殊行为对于不熟悉的读者来说并不明显,因此我们建议仅在 for_each
参数和类似情况下使用它,在这些情况下,上下文暗示与集合一起使用。否则,表达式的含义可能对未来的读者来说不清楚。
旧版(仅属性)Splat 表达式
早期版本的 OpenTofu 语言具有 splat 表达式的一个略有不同的版本,OpenTofu 继续为了向后兼容性而支持它。此较旧的变体不如上面描述的现代形式有用,因此我们建议不要在新的配置中使用它。
旧版“仅属性”splat 表达式使用序列 .*
,而不是 [*]
var.list.*.interfaces[0].name
这种形式的行为略有不同,等效于以下 for
表达式
[for o in var.list : o.interfaces][0].name
请注意,对于仅属性的 splat 表达式,索引操作 [0]
应用于迭代的结果,而不是作为迭代本身的一部分。只有属性查找适用于输入的每个元素。这种限制让一些使用旧版 OpenTofu 的人感到困惑,因此我们建议始终使用带 [*]
的新式 splat 表达式,以获得更一致的行为。