向關注這個系列的朋友們,道一聲:久違了!
它並沒有被我閹掉,他一定會得善終的,請各位不要灰心
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
今天就寫到這裡吧!
喜歡的人請幫忙點個推薦!