4. Lists
4.1 概述
WTCD 允许存储有序不可变列表。其类型名为 list
。
WTCD 的列表内的元素可以有不同的类型,因此一个长度为 1 的 list
可以被视为是一个可以存储任何类型值的 WTCD 变量。
4.2 创建新的列表
若要创建一个新的列表,请使用 [
和 ]
包裹这个列表里的元素。两个元素之间仅需要空格或是换行:
declare list a = [ 1 "Hello" 3 ]
此外,在定义变量时,若使用的类型是 list
,并不提供初始值的话,将会默认创建一个空的列表。
declare list empty // []
需要注意的是,这里有一个坑。下述代码:
declare list a = [ 1 -2 3 ]
会被 WTCD 理解为 [ (1 - 2) 3 ]
。若要解决这个问题,则需要使用:
declare list a = [ 1 (-2) 3 ]
4.3 获得列表的一个成员
若要获得列表的一个成员,则需要使用成员访问操作符:.
,.?
,?.
,?.?
。
4.3.1 普通成员访问
通常来说,访问一个成员使用 .
操作符:
[ "a0" "a1" "a2" "a3" ] . 2 == "a2"
[ "a0" "a1" "a2" "a3" ].(2) == "a2"
由于小数原因,WTCD 不允许直接写 [ "a0" "a1" "a2" "a3" ].2
。点与数字之间必须要要用空格隔开,或者用括号把数字包起来。
如果要访问的下标(Index)存在变量里,则可以直接写:
declare number index = 2
[ "a0" "a1" "a2" "a3" ].index == "a2"
需要注意的是,WTCD 的设计提倡“错误尽早发现”,因此当下标不存在(Index out of bounds)或是不正确时,普通成员访问会直接报错。需要注意的是,报错只会在下标不存在时发生。以下例子会正常返回 null
。
[ "a0" null "a2" ].(1) == null
而这个例子会报错:
[ "a0" "a1" ].(2) // List does not have an element at 2. If return null is desired, use ".?" instead. List contents: list (elements = [string (value = "a0"), string (value = "a1")])
4.3.2 越界即空成员访问
当然,有时候,确实会希望当下标不存在时返回 null
。这时候可以使用 .?
来访问成员。
[ "a0" "a1" ] .? (2) == null
需要注意的是,只有下标越界的时候(index < 0
或者 index >= listLength::[list]
),.?
才会返回 null
。如果提供的下标不是整数依然会报错。(无论如何,你都不应该在下标中使用涉及浮点数运算的操作。)
4.3.3 可选成员访问
还有某些时候,列表本身也可能是 null
。如果希望在这个情况下不报错而是直接返回 null
,可以使用 ?.
。
null ?. 2 == null
需要注意的是,?.
是带有 short circuit 的。也就是说,如果左侧计算结果为 null
,那么右侧的内容根本不会被计算。
4.3.4 可选越界即空成员访问
如果凑巧,不但你希望在下标越界时返回 null
,而且在列表自己是 null
的时候也返回 null
,你可以使用 ?.?
。
null ?.? 2 == null
[ 0 1 2 ] ?.? 3 == null
4.4 改变列表
简而言之,你不能改变列表。
—— 但是你可以从一个列表创建一个稍稍有点不同的列表。
4.4.1 使用标准库函数
最简单的改变列表的方式是使用标准库(见第 6 章)函数(见第 5 章) listSet
。
declare list a = [ 0 1 2 3 ]
declare list b = listSet::[a 2 "Wow"] // b 是 [ 0 1 "Wow" 3 ]
需要注意的是,正如之前所说,listSet
不会改变列表,你必须把返回值赋给一个之前的或是另一个变量。
declare list a = [ 0 1 2 3 ]
listSet::[a 2 "Wow"]
// a 依然是 [ 0 1 2 3 ]
a = listSet::[a 2 "Wow"]
// a 现在是 [ 0 1 "Wow" 3 ] 了
关于其他改变列表的函数,请前往 6.1
。
4.4.2 使用 ...
操作符
...
允许用一个数组代替一个新的数组的一部分。
举个例子:
declare list inner = [ 3 4 5 ]
declare list outer = [ 1 2 ...inner 6 7 ] // [ 1 2 3 4 5 6 7 ]
使用 ...
可以获得一个在一个列表的基础上加了若干元素的列表。(添加元素)
declare list a = [ 1 2 3 ]
a = [ ...a "Back" ] // [ 1 2 3 "Back" ]
a = [ "Front" ...a ] // [ "Front" 1 2 3 "Back" ]
或者可以做点别的事情比如:
declare list a = [ 1 2 3 ]
a = [ ...a ...a ] // [ 1 2 3 1 2 3 ]