Nim教程【九】
向关注这个系列的朋友们,道一声:久违了!
它并没有被我阉掉,他一定会得善终的,请各位不要灰心
Set集合类型
为了在特殊场景下提高程序的性能设置了Set类型,同时也是为了保证性能,所以Set只能容纳有序类型,
Set类型可以被一个大括号实例化:
var x = {},x就是一个空的set类型
还可以在大括号构造符号内部填写set变量内部的元素,或一组元素
就像下面的代码一样
type CharSet = set[char] var x: CharSet x = {'a'..'z', '0'..'9'}
可以用于Set类型的操作符
操作符 | 含义 |
A + B | union操作,链接两个Set变量 |
A * B | 得到两个集合的交集 |
A - B | 得到两个集合的差异(A中哪些元素是B所不包含的) |
A == B | 判断两个集合是否相等 |
A <= B | A是否与B相等或者A是否是B的子集 |
A < B | A是否是B的子集 |
e in A | A包含元素e |
e notin A | A不包含元素e |
contains(A,e) | A包含元素e |
Card(A) | A中包含多少个元素 |
incl(A,e) | 与A = A + {e}相同 |
excl(A,e) | 与A = A - {e}相同 |
Array数组类型
数组是一个固定长度的容器
数组中的每个元素必须类型相同
数组可以使用方括号构造
请看下面的代码
type IntArray = array[0..5, int] # an array that is indexed with 0..5 var x: IntArray x = [1, 2, 3, 4, 5, 6] for i in low(x)..high(x): echo(x[i])
代码中x[i]的意思是访问数组x的第i个元素
nim语言会对数组访问执行边界检查
你通过开关的形式来设置:到底是在编译期执行边界检查,还是在运行期执行边界检查
(译注:我们这里就不讲怎么设置这个开关了)
数组是值类型的,像其他值类型一样,赋值操作将复制整个数组内容
len方法返回数组的长度
low方法返回数组的最小下标
high方法返回数组的最大下标
请仔细看一下下面的代码:
type Direction = enum north, east, south, west BlinkLights = enum off, on, slowBlink, mediumBlink, fastBlink LevelSetting = array[north..west, BlinkLights] var level: LevelSetting level[north] = on level[south] = slowBlink level[east] = fastBlink echo repr(level) # --> [on, fastBlink, slowBlink, off] echo low(level) # --> north echo len(level) # --> 4 echo high(level) # --> west
可以用多个方括号来实现多维数组
在多维数组中,不同的纬度可以拥有不同的索引类型
来看一下下面的代码
type Direction = enum north, east, south, west BlinkLights = enum off, on, slowBlink, mediumBlink, fastBlink LevelSetting = array[north..west, BlinkLights] LightTower = array[1..10, LevelSetting] var tower: LightTower tower[1][north] = slowBlink tower[1][east] = mediumBlink echo len(tower) # --> 10 echo len(tower[1]) # --> 4 echo repr(tower) # --> [[slowBlink, mediumBlink, ...more output.. # The following lines don't compile due to type mismatch errors #tower[north][east] = on #tower[0][1] = on
注意:len(tower)只返回第一维数组的长度
我们还可以通过下面的方式定义多维数组,(可读性更好一些)
type LightTower = array[1..10, array[north..west, BlinkLights]]
还有一种简单的定义数组的方法,来看看下面的代码
type IntArray = array[0..5, int] # an array that is indexed with 0..5 QuickArray = array[6, int] # an array that is indexed with 0..5 var x: IntArray y: QuickArray x = [1, 2, 3, 4, 5, 6] y = x for i in low(x)..high(x): echo(x[i], y[i])
从上面的代码中可以看出,定义数组的时候,不必每次都要指定数组的最小下标
seq序列类型
seq类型类似于数组,但seq类型可以在运行期改变容器的长度;
也正是因为seq是长度可变的,所以nim在内存堆上为它分配空间和进行垃圾收集
seq类型的索引总是从0开始的,
len、low、high操作同样适用于seq类型
可以通过x[i]访问seq类型的x变量的第i个元素
seq类型可以通过@和方括号来构造,也可以使用内置的newSeq方法来构造
请看下面的代码
var x: seq[int] # a sequence of integers x = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
如果你没有为一个seq类型的变量赋值,那么它的默认值将为nil
在很多应用在seq变量的操作中,操作nil的话会抛出异常
所以很多人都会为seq类型的变量设置空值:@[]
但是设置空值的话,会在内存堆上创建一个空序列
一定程度上有损性能
请你自行斟酌权衡吧
用for语句遍历一个序列的时候,for语句中可以存在一个或两个变量
如果是一个变量的时候,
这个变量将持有每次迭代过程中seq提供的值
如果是两个变量的时候,
第一个变量将保存索引的位置
第二个变量将保存seq提供的值
请看下面的代码:
for i in @[3, 4, 5]: echo($i) # --> 3 # --> 4 # --> 5 for i, value in @[3, 4, 5]: echo("index: ", $i, ", value:", $value) # --> index: 0, value:3 # --> index: 1, value:4 # --> index: 2, value:5
今天就写到这里吧!
喜欢的人请帮忙点个推荐!