[Raku] 程式設計教學:變數 (Variable) 和資料型別 (Data Types)

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    註記

    Perl 6 已經更名為 Raku,目前 (西元 2019 年 10 月) 是轉換期。現階段用 Perl 6 當關鍵字可以找到比較多的學習資源,之後會慢慢遷移到 Raku 上。

    實字 (Literal)

    實字 (literal) 指的是在程式中直接寫死的資料,例如:

    • True (布林)
    • 3.14159 (數字)
    • "Hello World" (字串)
    • (1, 2, 3) (串列)

    在初期的練習中,我們會用實字來生成程式要用的資料,這樣比較方便。但在實用的程式中,我們會由外部讀入資料,使用實字的機會就少一些。

    宣告變數 (Variable)

    在電腦程式中,變數 (variable) 是資料的標籤。我們藉由變數來操作資料。這裡以 Raku 的角度來看變數如何使用。

    在使用變數前,要先宣告變數。一般來說,使用 my 宣告變數,實例如下:

    my $msg = "Hello World";
    say $msg;
    

    雖然 Raku 可以用 Unicode 字元宣告變數名稱,因 Unicode 無法直接用鍵盤打出來,建議還是使用英文字母來宣告變數。

    選擇性的型別標註

    Raku 是動態型別語言,但可選擇性地註記型別,若加入型別註記,Raku 會協助我們檢查變數的型別,型別錯誤時會引發程式錯誤。如以下反例:

    my Str $v = "Hello World";
    
    $v = 12345;  # Error.
    
    say $v;
    

    在此反例中,變數 $v 的型別已標註為 Str (字串),但我們使用整數 12345 重新賦值,這時會引發錯誤。

    註:此特性為 gradual typing。

    對於簡短的命令稿 (scripts),通常不會加上型別註記。若要開發套件或中大型程式,加入型別註記對於程式碼品質會有幫助。

    宣告常數 (Constant)

    對於常數,可改用 constant 宣告,避免無意間修改造成的錯誤,如以下反例會引發錯誤:

    constant $pi = 3.14159;
    
    $pi = 4;  # Error.
    

    變數的前綴 (Sigil)

    Sigil 是 Perl 家族程式語言的特色,用來當做變數的標註 (annotation),讓程式設計師一看就知道該變數的形態。

    Raku 的變數使用四種 sigil:

    • $:用於純量 (scalar)
    • @:用於陣列 (array)
    • %:用於雜湊 (hash) 或關連性陣列 (associative array)
    • &:用於副常式 (subroutine)

    在 Perl 5 時,sigil 的規則比較複雜,初學 Perl 的程式人容易搞混。Raku 將 sigil 的規則簡化,變數不需要在不同形態間變換 sigil,同一個變數使用同一種 sigil 即可。

    Raku 有許多影響變數可變範圍 (scope) 的語法,像是 twigil 或是其他的變數宣告關鍵字,一開始學習時,不需過度在意這些細節,先用 myconstant 宣告變數和常數即可。

    特殊變數 (Special Variables)

    Raku 有許多特殊變數,但和 Perl 5 的內建變數不同,大部分 Raku 的特殊變數是以字母來標示,比較好閱讀。僅有少數特殊變數用符號表示,如下:

    • $_:用於區塊的預設變數
    • $/:常規表示式比對的結果
    • $!:例外處理的結果

    其他的特殊變數請參考 Raku 官網的文件

    建立識別字 (Identifier)

    變數名稱在程式中又稱為識別字 (identifier)。識別字原本是沒有意義的,是由程式撰寫者透過宣告變數的方式讓識別字產生意義。在 Raku,有以下三種風格的識別字命名方式:

    • aLongVariable (camel case)
    • a_long_variable (snake case)
    • a-long-variable (kebab case)

    Raku 沒有限制使用那一種命令方式,通常是在程式中選擇一種後就保持一致。但筆者較不建議用 kebab case,因為大部分程式語言不支援這種寫法,不要養成這種習慣比較好。

    一般程式設計書籍,傾向用簡短的變數名稱,像是 $var$n$i 等,這是為了便利性。但是,實際在撰寫程式時,使用有意義的名稱較易閱讀。以下是反例:

    $var1 = $var2 * $var3;
    

    雖然這個程式可正確運作,但從程式碼無法得知程式的意圖。將其改寫如下:

    $monthly-salary = $daily-rate * $working-days;
    

    對於電腦程式來說,兩個程式的意義相同,但本例較易閱讀,日後要維護也比較方便。

    內部用變數,像是迴圈、副常式、類別等,可以用較短的名稱,但對外的變數,則以有意義的名稱較佳。

    表達式 (Expression) 和敘述式 (Statement)

    表達式 (expression) 指的是會回傳值的代碼,如下:

    • 42
    • "Hello"
    • $n + 1

    敘述式 (statement) 則是指會產生某種效果的程式碼,如下:

    • my $n;
    • $n = 42;
    • say "Hello World";

    大部分的程式語言,是以指令式 (imperative) 和物件導向 (object-oriented) 為主流範式 (paradigm);這兩類程式都是以撰寫敘述式為主。

    資料型別 (Data Type)

    Raku 是物件導向語言,實踐萬物皆物件 (everything is object) 的概念。以下是一些常見的 Raku 物件:

    • Bool:布林數
    • 數字相關的類別:
      • Int:任意精確度整數
      • Rat:有理數
      • FatRat:任意精確度有理數
      • Num:倍精確度浮點數 (類似 C 語言的 double)
      • Complex:複數
    • Str:字串
    • 日期相關的類別:
      • Date:日期
      • DateTime:包含時間的日期

    由於 Raku 型別系統有複雜的繼承關係,直接看 Raku 官網容易看不懂,先記得幾個常用的型別即可。

    布林 (Boolean)

    布林 (boolean) 只有 TrueFalse 兩種值,主要用於條件判斷中。

    數字 (Number)

    Raku 常用的數字表示方式如下:

    • 十進位:12345,最常見的表示法
    • 十六進位::16<FF>
    • 八進位::8<755>
    • 二進位::2<10101>

    甚至可以用其他介於 2 至 36 間的位數:

    • 五進位::5<342>
    • 三十進位::30<102squr>

    數字可以用底線分隔,視覺上較美觀,如 123_456_789

    Raku 的數字系統和一般程式語言略為不同,以下的程式會引發錯誤:

    $ ruby -e 'raise "Unequal" unless 0.1 + 0.2 - 0.3 == 0.0'
    

    但以下的 Raku 程式可正確執行:

    $ perl6 -e '0.1 + 0.2 - 0.3 == 0.0 or die "Unequal";'
    

    這是因為 Raku 內部使用 Rat 儲存有理數,不會有浮點數造成的微小誤差。由於這項特性幾乎不會出現在其他程式語言,最好把這項特性當成特例,不要過度依賴這項特性。

    字串 (String)

    在 Raku 中,用以下方式可以撰寫字串實字:

    • 一對單引號
    • 一對雙引號
    • q 加上成對符號,相當於一對單引號
    • qq 加上成對符號,相當於一對雙引號

    以下是實例:

    q<Hello World> eq "Hello World" or die "It should be equal";
    

    在這個例子中,我們使用兩種方式來撰寫相同的字串實字,故其值相等。

    物件 (Object)

    除了使用現有的型別外,我們也可以透過物件導向增加新的型別。

    Perl 一開始不支援物件導向,Perl 5 的物件系統是後來才附加上去的,相對較為原始。Perl 社群參考 Raku 的物件系統,引入 Moose 後,Perl 5 才有比較進步的物件系統。

    相對來說,Raku 支援原生的物件導向語法,和 Moose 的語法差不多。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤新文章】
    Facebook Twitter Plurk