稱重機

稱重機

學習練習

簡介

Getter 與 setter 是方法,讓你可以讀取和寫入物件屬性的值。 Crystal 有巨集,這讓為屬性定義 getter 和 setter 變得輕鬆。 巨集是一種在編譯期產生程式碼的方式,之後會在巨集概念中介紹。

在 Ruby 中,這些方法是使用 attr_reader、attr_writer 和 attr_accessor 方法定義的,表面上和 Crystal 的實作非常相似。 Crystal 則將它們定義成 getter、setter 和 property 巨集。

Getter

Getter 是一個巨集,它會定義一個回傳實例變數值的方法。 這表示當你想存取實例變數時(在方法中,不含 initialize),不再需要在它前面寫 @;取而代之的是,你可以呼叫 getter 巨集所定義的方法。

getter 巨集可以接受多個實例變數,只要用逗號分隔即可。

# This:
class Person
  @name : String
  @age : Int32

  def name
    @name
  end

  def age
    @age
  end
end

# Is the same as this:
class Person
  @name : String
  @age : Int32

  getter name, :age
end

如你所見,使用 getter 可以減少你撰寫的程式碼量,也讓程式更好讀。 此外,Ruby 和 Crystal 有一點不同:Crystal 的 getter 巨集同時接受變數名稱和符號作為引數。 符號之後會在符號概念中介紹。

Setter

Setter 是一個巨集,它會定義一個設定實例變數值的方法。 這個巨集不常單獨出現,通常會改用 property 巨集。 建立出來的方法會長得像 name_of_method=;其中的 = 就是讓屬性可以被設定的關鍵。

這種方法定義比較特別,因為方法接收的引數放在 = 符號之後。 Crystal 中還有其他幾個特殊方法也使用這種語法,例如 + 方法。

和 getter 巨集一樣,定義 setter 之後,當你想更新實例變數的值時,可以呼叫 setter 巨集所定義的方法。

# This:
class Person
  @name : String
  @age : Int32

  def name=(name : String)
    @name = name
  end

  def age=(age : Int32)
    @age = age
  end
end

# Is the same as this:
class Person
  @name : String
  @age : Int32

  setter name, :age
end

Property

Property 是一個巨集,它會為實例變數同時定義 getter 和 setter。

class Person
  @name : String
  @age : Int32

  property name, :age
end

說明

在這個練習中,你將會模擬一台秤重機。

1. 建立秤重機的初始狀態

初始化時,秤重機應該採用出廠設定,而出廠設定會依機器銷售的地區而有所不同。 因此,這台機器應該要能在初始化時指定精確度,以及是否使用公制。

請實作 WeighingMachine#initialize 方法,它接受兩個引數:precision(型別為 Int32)和 metric(型別為 Bool)。 metric 引數為 true 時,表示機器應該使用公制,否則應該使用英制。 這個 initialize 方法也應該將實例變數 @weight 設為 0.0。

precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)

2. 讓秤重機具備精確度

為了滿足不同的需求,我們讓每台秤重機都能自訂精確度(小數分隔符後面的位數)。

請實作 WeighingMachine#precision 取值方法,回傳秤重機的精確度。

precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)
vm.precision
# => 3

3. 讓秤重機可以設定重量

請實作 WeighingMachine#weight 屬性,讓重量可以被取得和設定:

precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
wm.weight = 60.5
wm.weight
# => 60.5

wm.weigh
# => 60.5

4. 讓機器可以在公制和英制單位之間切換

請實作 WeighingMachine#metric= 屬性,讓單位可以被設定。 它應該接受布林值。

precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
vm.weight = 60.5
wm.metric = false

vm.weigh
# => 133.377
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Crystal Exercism

準備好開始 稱重機 了嗎?

註冊 Exercism,透過 26 個概念142 個練習 和真人引導來學習並精通 Crystal,全部免費。