解构赋值
解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。
通常当你看到一个字面量的 Lua 表,比如 {1,2,3},它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量 Lua 表的角色,并将其放在赋值语句的左侧。
最好是通过示例来解释。以下是如何从表格中解包前两个值的方法:
thing = [1, 2]
[a, b] = thingprint a, bthing = [1, 2]
[a, b] = thingprint a, b在解构表格字面量中,键代表从右侧读取的键,值代表读取的值将被赋予的名称。
obj = { hello: "world" day: "tuesday" length: 20}
{hello: hello, day: the_day} = objprint hello, the_day
:day = obj -- 可以不带大括号进行简单的解构obj = { hello: "world" day: "tuesday" length: 20}
{hello: hello, day: the_day} = objprint hello, the_day
:day = obj -- 可以不带大括号进行简单的解构这也适用于嵌套的数据结构:
obj2 = { numbers: [1,2,3,4] properties: { color: "green" height: 13.5 }}
{numbers: [first, second], properties: {color: color}} = obj2print first, second, colorobj2 = { numbers: [1,2,3,4] properties: { color: "green" height: 13.5 }}
{numbers: [first, second], properties: {color: color}} = obj2print first, second, color如果解构语句很复杂,也可以任意将其分散在几行中。稍微复杂一些的示例:
{ numbers: [first, second] properties: { color: color }} = obj2{ numbers: [first, second] properties: { color: color }} = obj2有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 : 前缀操作符:
{:concat, :insert} = table{:concat, :insert} = table这样的用法与导入语法有些相似。但我们可以通过混合语法重命名我们想要提取的字段:
{:mix, :max, random: rand} = math{:mix, :max, random: rand} = math在进行解构时,你可以指定默认值,如:
{:name = "nameless", :job = "jobless"} = person{:name = "nameless", :job = "jobless"} = person 在进行列表解构时,你可以使用_作为占位符:
[_, two, _, four] = items[_, two, _, four] = items 你可以使用展开运算符 ... 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。
orders = ["first", "second", "third", "fourth", "last"][first, ...bulk, last] = ordersprint first -- 打印: firstprint bulk -- 打印: {"second", "third", "fourth"}print last -- 打印: lastorders = ["first", "second", "third", "fourth", "last"][first, ...bulk, last] = ordersprint first -- 打印: firstprint bulk -- 打印: {"second", "third", "fourth"}print last -- 打印: last 展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 _ 作为占位符来表示你想跳过对应范围的捕获:
-- 捕获第一个元素之后的所有元素[first, ...rest] = orders
-- 捕获最后一个元素之前的所有元素[...start, last] = orders
-- 跳过中间的元素,只捕获第一个和最后一个元素[first, ..._, last] = orders-- 捕获第一个元素之后的所有元素[first, ...rest] = orders
-- 捕获最后一个元素之前的所有元素[...start, last] = orders
-- 跳过中间的元素,只捕获第一个和最后一个元素[first, ..._, last] = orders在其它地方的解构赋值
Section titled “在其它地方的解构赋值”解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中:
tuples = [ ["hello", "world"] ["egg", "head"]]
for [left, right] in *tuples print left, righttuples = [ ["hello", "world"] ["egg", "head"]]
for [left, right] in *tuples print left, right我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。