Crystal 有一種型別叫做Nil,它只能有一個值:nil。它用來表示「沒有值」,類似於其他語言中的null或None。
Nil 值可以從各種方法回傳,例如String#[]?,當索引超出範圍時,它會回傳nil。
"foo"[10]? # => nil
Crystal 有項機制叫做空參考檢查,意思是所有型別預設都不可為 nil。這表示除非你明確把變數宣告成Nil型別,否則不能把nil指定給變數。因此編譯器會自動檢查空參考。
處理nil值有幾種做法。nil是假值,false也是。這表示在敘述,以及其他預期假值或真值的地方,nil都會被當成false看待。
if nil
puts "nil is truthy"
else
puts "nil is falsey"
end
# => nil is falsey
這表示如果一個可為 nil 的變數值為nil,就不會進入真值分支。
foo = "boo"[2]? # It is possible that foo is nil
if foo
p foo.class # => Char
end
Crystal 有個方法可以檢查某個值是否為nil,叫做nil?,所有物件都可以使用。
foo = "boo"[2]?
if foo.nil?
puts "foo is nil"
else
puts "foo is not nil"
end
直接把值用在 if 敘述裡時,情況會有點不同,因為在前面的例子裡,false和nil都會被當成假值。這裡只有nil會被當成假值,因為如果它的值是false,那它就不會是nil,因此會是真值。
處理nil值最簡單的方法,就是從一開始就確保它們不會變成nil。or 運算子(||)經常用來處理Bools,但只要理解正確,它也能用來處理nil值。or 運算子會檢查第一個值是否為真值,如果不是,就採用第二個值。如此一來,如果值是nil,就會是假值,因此會採用第二個值。
"foo"[10]? || "bar" # => "bar"
陛下即將在卡爾馬聯盟的首都哥本哈根舉辦一場晚宴。 這是年度最盛大的宴會,所有貴族都受邀參加。 但全國上下正謠傳著有人密謀要毒害陛下。
女王陛下請你這位皇家毒物搜查員,查出是否有任何食物或飲料被下毒。 陛下打算只供應Mushroom pasties作為食物,但飲料方面則有各式各樣的選擇。
如果食物不是女王陛下點的東西,那它被下毒的機率就很高。 若食物不是女王陛下點的,就應該把它丟掉。
請實作check_food?方法,它接受引數food,該引數以String的形式存放食物名稱。
如果食物是Mushroom pasties,方法應該回傳該食物;否則應該回傳nil。
CastleDinner.check_food?("Mushroom pasties")
# => "Mushroom pasties"
CastleDinner.check_food?("Bread")
# => nil
飲料有可能被下毒,但要判斷出來稍微困難一些。
如果飲料名稱中沒有包含字母i,那它就被下毒了,大小寫不拘。
飲料若被下毒,就應該倒掉。
請實作check_drink?方法,它接受引數drink,該引數以String的形式存放飲料名稱。
如果飲料沒有被下毒,方法應該回傳該飲料;否則應該回傳nil。
CastleDinner.check_drink?("Apple juice")
# => "Apple juice"
CastleDinner.check_drink?("Tea")
# => nil
陛下不會想讓賓客擔心食物裡有毒。 因此,如果飲料被下毒,就應該換成新的飲料,也就是Apple juice。
請實作replace_drink方法,它接受引數drink,該引數以String的形式存放飲料名稱。
如果飲料沒有被下毒,方法應該回傳該飲料;否則應該回傳"Apple juice"。
CastleDinner.replace_drink("Orange juice")
# => "Orange juice"
CastleDinner.replace_drink("Tea")
# => "Apple juice"