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

今天就写到这里吧!

喜欢的人请帮忙点个推荐!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Crossin的编程教室

【编程课堂】计数器 Counter

上一期的编程课堂我们介绍了 有序字典 OrderedDict,这一期我们再来聊聊 同属 collections 模块的另一种数据类型 Counter。 在了解 ...

30460
来自专栏向治洪

Java泛型和通配符那点事

泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数...

24750
来自专栏Android知识点总结

1-VI--随机数据生成

14240
来自专栏流媒体

STL(二)map/multimapmapmultimap

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力。由于这个特...

11930
来自专栏Python研发

一起来学Go --- (go的枚举以及数据类型)

枚举指一系列的相关的常量,比如下面关于一个星期的中每天的定义,通过上篇博文,我们可以用在const后跟一对圆括号的方式定义一组常量,这种定义法在go语言中通常用...

10810
来自专栏陈树义

如何检测链表中是存在循环

  链表在面试中出现的频率很高,有的比较正常,考链表的常规操作,主要看基本功是否扎实,有些就比较难,难在思维的改变和是否能够想到对应的点。这里出现的是其中一个题...

35650
来自专栏java一日一条

Java 回顾 ( Revisiting Java )

最近在看一些工程代码,于是看了看设计模式,看设计模式之前发现Java是先修知识,又重新补了一遍Java,温故知新,获得一些新的体会。 本文不打算作为“Java知...

9120
来自专栏mukekeheart的iOS之旅

final、finally、finalize的区别

final:修饰符,可以用于修饰成员、方法和类。 如果一个类被声明为final,意味着该类不能再派生出新的子类,不能作为父类被继承。因此一个类不能即被声明为ab...

25050
来自专栏移动端开发

Swift 面向对象解析(一)

面向对象总体概括: Swift 不仅能够面向过程编程,也能够面向对象编程(OOP)。面向对象其实就是“以对象为核心”,把我们的客观世界想着是由一个个对象组...

22570
来自专栏个人随笔

房上的猫:楼主错题:解析

本题考查的是对java中数组的相关知识, 数组一旦定义就不能改变大小了;数组中存放的都是同一类型的数据;数组的下标是从0开始的,也就是说下标为0的位置存放的是第...

412110

扫码关注云+社区

领取腾讯云代金券