跳至主要内容

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 表达式,以获得更一致的行为。