Perl 6 程式設計教學:變數和資料型別

實字

實字 (literal) 指的是固定的值,例如:

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

變數

變數 (variable) 的作用在於暫存值,再透過程式操作。變數像是有標籤的盒子,變數名稱是標籤,而值存在盒子中。

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

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

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

註:此特性為 gradual typing。

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

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

Perl 6 變數有四種 sigil (變數字首):

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

Perl 6 將 sigil 簡化,不需要在不同資料類型間變換 sigil,同一個變數使用同一種 sigil 即可。

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

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

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

其他的特殊變數請參考 Perl 6 官網。

變數名稱

在 Perl 6,有以下三種風格的變數命名方式:

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

Perl 6 沒有限制使用那一種命令方式,通常是在程式中選擇一種後就保持一致。

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

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

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

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

表達式和敘述式

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

  • 42
  • "Hello"
  • $n + 1

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

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

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

型別

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

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

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

布林

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

數字

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

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

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

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

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

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

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

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

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

這是因為 Perl 6 內部使用 Rat 儲存有理數,不會有浮點數造成的微小誤差。

物件

我們也可以透過物件導向增加新的型別;Perl 5 的物件導向是後來才附加上去的,相對較為原始,Perl 社群引入 Moose 後,Perl 5 才有比較進步的物件系統;但 Perl 6 支援原生的物件導向語法,和 Moose 的語法差不多。