學習軌道
/
Gleam
Gleam
/
練習
/
安全寶箱
安全寶箱

安全寶箱

學習練習

簡介

不透明型別

Gleam 中的不透明型別是一種自訂型別,只有定義該型別的模組才能建構或模式配對這種型別的值。當你希望某個型別只能以特定方式使用時,這就很有用。

不透明型別是用opaque關鍵字定義的。

pub opaque type PositiveInt {
  PositiveInt(inner: Int)
}

這個PositiveInt型別適合用在需要整數、而且該整數必須大於或等於零的情境。一般的 Gleam Int無法勝任,因為它也可以是負數。

定義這個型別的模組可以定義一個函式來取得內部的整數值,也可以定義一個建立PositiveInt型別的函式,後者在傳入的值不是正數時會回傳錯誤。

pub fn from_int(i: Int) -> Result(PositiveInt, String) {
  case i {
    _ if i < 0 -> Error("Value must be positive")
    _ -> Ok(PositiveInt(i))
  }
}

pub fn to_int(i: PositiveInt) -> Int {
  i.inner
}

有了這組 API,其他模組就無法建構出帶有負數值的PositiveInt,因此任何接受PositiveInt的函式都能確定這個值是正數。

說明

眼尖的學生應該已經發現,前一個練習裡的TreasureChest型別其實沒那麼安全!

使用get_treasure函式時,你必須提供密碼,但你還是可以解構TreasureChest型別,在不知道密碼的情況下取得寶藏。

我們就用不透明型別來解決這個問題吧。

1. 定義TreasureChest不透明型別

TreasureChest包含兩個欄位:

  • 一個String型別的密碼。
  • 一個泛型型別的寶藏。

TreasureChest型別必須是不透明的。

2. 定義create函式

這個函式接受兩個引數:

  • 一個String型別的密碼。
  • 任意型別的寶藏值。

函式會回傳一個TreasureChest,其中包含密碼和該值。

如果密碼少於 8 個字元,函式應該回傳一個錯誤,內容為Password must be at least 8 characters long。

3. 定義open函式

這個函式接受兩個引數:

  • 一個TreasureChest。
  • 一個String型別的密碼。

如果密碼與TreasureChest裡的密碼相符,函式應該回傳寶藏,否則應該回傳一個錯誤,內容為Incorrect password。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Gleam Exercism

準備好開始 安全寶箱 了嗎?

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