Nim教程【六】

liulun發表於2015-05-20

目前看來這是國內第一個關於Nim的系列教程

先說廢話

        Rust1.0已經發布了,

        國內有一個人為這個事情寫了一篇非常長的部落格

        這篇文章我前幾天草草的看了一下,只記得這位朋友追Rust的艱辛,其他內容都已經記不清楚了

        我覺得,任何正向付出都是值得鼓勵和尊敬的

        這節不對其他語言做任何吐槽

        就吐槽Nim本身,

        Nim這個語言之前叫做Nimrod,意思是獵人,

        是一個聖經裡的人物,曾經做過國王,大概是英勇善戰、威風八面的人物吧

        關鍵是Nimrod這個單詞的讀音:['nɪmrɒd]

        真是叫人擔心啊,居然讀作“尼瑪的”!哈哈

        (不過據說國內go語言圈裡有一個人物在開發yin語言,我想名字的讀音上也沒有什麼高下之分吧)

迭代器

        先來看看我們上幾篇部落格提到的有關迴圈的程式碼

echo("Counting to ten: ")
for i in countup(1, 10):
  echo($i)

       countup就是一個迭代器,他是怎麼實現的呢?

        先來看一個錯誤的例子

proc countup(a, b: int): int =
  var res = a
  while res <= b:
    return res
    inc(res)

        這是不對的,因為對於一個方法來說,return之後就退出了這個方法,return有沒有在迴圈體內部

        那麼我們看看正確的寫法是怎樣的

iterator countup(a, b: int): int =
  var res = a
  while res <= b:
    yield res
    inc(res)
    • 這並不是用proc宣告的方法,而是用iterator宣告的迭代器

    • 迭代器內部可以用yield關鍵字“迭代”返回某一個變數的值(很像C#)

    • 迭代器只能用在for迴圈中

    • 迭代器中不能包含return關鍵字

    • 方法中也不能包含yield關鍵字

    • 迭代器中並沒有一個隱藏的result變數

    • 迭代器不支援遞迴

    • 迭代器不支援前置宣告(這項要求將在未來的編譯器中被刪掉)

        關於迭代器還有很多內容,我們將在後面的章節再聊

bool型別

        bool型別有兩個值:true和false

        用在while,if ,elif,when這些流程控制語句中,用於判斷是否滿足條件

        諸如:not,and,or,xor,<,<=,>,>=,!=,==這類操作符,計算的結果就是bool型別的值

        來看個例子:

while p != nil and p.name != "xyz":
  # p.name is not evaluated if p == nil
  p = p.next

字元型別

        關鍵字是char,這種型別佔據一個位元組,因此它不能表示一個UTF-8的字元,

        但是它可以用於表示一個UTF-8字元的一部分,這麼搞主要是為了提升效能。

        for the overwhelming majority of use-cases, 

        the resulting programs will still handle UTF-8 

        properly as UTF-8 was specially designed for this(這一句不敢亂翻譯)

        用單引號包住一個字元,就可以為字元型別的變數設定值了

        諸如==,<,>,<=,>=這些操作符,可以用來操字元型別

        $操作符可以把一個字元型別格式化成字串型別

        字元型別不能和數字型別混淆,要想得到一個字元型別的“序數值”,請使用ord方法

        把一個數字型別的值格式化成字元型別,請使用chr方法

字串型別

        字串型別是一個mutable型別(可變型別),

        因此,對於一個字串的拼接操作來說,效能表現非常好;

        Nim中的字串型別是以\0結尾的(與C語言相似)

        但Nim中的字串型別還包含一個長度的屬性(這樣你取一個字串的屬性,就非常高效了)

        這個屬性不會計算字串結尾的\0字元

        你可以通過len方法獲得一個字串的長度,

        另外,還有一個值得注意的地方:

if s[i] == 'a' and s[i+1] == 'b':

        像這樣的程式碼,是不用檢測i+1是不是已經到了字串的結尾的

        也就是說,方位字串的最後一個索引(\0位置的索引),不會有問題

        

        賦值運算子會導致一個字串被複制

        你可以使用&運算子來連結兩個字串

        (你也可以使用add運算子,來把一個字串新增到另一個字串的結尾)

 

        字串的比較是按字串內的字元順序做比較的

        所有的比較操作符都可以用在字串身上

        按照慣例,所有的字串都是UTF-8型別的字串,但這並不是強制執行的

        當你從一個二進位制檔案中讀取資料的時候,他僅僅是一系列的位元組

        s[i]是指在i位置的字元char,而不是在i位置的unichar

 

        string型別的變數預設值是nil,很多針對string型別的操作,都不能用在nil身上(這樣幹會觸發一個異常)

        如果你不希望這樣,那麼你最好用""來初始化你的字串變數(但這會導致在堆上建立一個“”字串變數)

        所以你自己做權衡吧!

 

 

今天就寫到這裡,喜歡的人請幫忙點推薦!

相關文章