Two Fer

Two Fer

簡單

簡介

在某些英語口音中,當你快速說出「two for」時,聽起來就像「two fer」。 「Two-for-one」的意思是,如果你買一個,就可以免費得到一個。 所以「two-fer」這個詞通常暗示著買一送一的優惠。

想像一家麵包店有個節日優惠,你可以用一塊餅乾的價格買到兩塊餅乾(「two-fer one!」)。 你接受了這個優惠,並且(非常慷慨地)決定把多出來的那塊餅乾給隊伍中的另一個人喔。

說明

你的任務是決定當你分送多出來的那塊餅乾時,要說什麼。

如果你知道對方的名字(例如對方叫 Do-yun),你會說:

One for Do-yun, one for me.

如果你不知道對方的名字,就改說 you。

One for you, one for me.

以下是一些例子:

名字 對話
Alice One for Alice, one for me.
Bohdan One for Bohdan, one for me.
One for you, one for me.
Zaphod One for Zaphod, one for me.

Odin 專屬的說明

Odin 支援預設引數。 預設引數是一項實用的功能,讓你在需要相關但不同 API 的情境下,可以用不同的參數組合來呼叫程序。

少了預設引數,你的 API 最後可能會需要數量爆炸的程序。不支援預設引數的程式語言(例如 Java)得靠方法多載來達到同樣的效果(程式碼也更多),不然就得提供帶有一大堆引數的程序。

讓我們以greeting程序為例,假設我們希望能指定語言、指定名稱是否要轉成大寫,以及問候語結尾是否要加上驚嘆號。經過分析後,我們發現最大一群使用者會指定英文、不把名稱轉成大寫,也不想要結尾有驚嘆號;第二大的族群則會在問候語結尾加上驚嘆號。

我們可以寫出一個包含所有引數的單一程序:

greeting :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {
	...
}

但這麼做會強迫所有使用者讀完每個引數的說明文件,而且每次都得把它們填滿。

沒有預設引數時,我們也可以定義多個帶有不同參數組合的程序:

greeting_common :: proc(name: string) {...}

greeting_with_exclamation :: proc(name: string) {...}

greeting_general :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {...}

// Odin supports overloading but it has to be explicitly defined
greeting :: proc {
	greeting_common,
	greeting_with_exclamation,
	greeting_general,
}

如果你的程式語言像 Odin 一樣支援預設引數,就可以直接為最少用到的引數提供合理的預設值。呼叫者可以略過預設引數,讓程序採用提供的預設值,也可以覆寫它們。

greeting :: proc(name: string, language: Language = Language.English, do_uppercase : bool = false, add_exclamation: bool = false) {...}

// Note: because Odin supports type inference, we can simplify the interface.
greeting :: proc(name: string, language:= Language.English, do_uppercase := false, add_exclamation:= false) {...}

這個程序可以完全只用預設引數來呼叫:

greeting("John Doe")

對呼叫者重要的引數則可以覆寫:

greeting("John Doe", Language.Spanish)

如果你需要的引數正好照位置順序排列,就像上面的例子那樣,就不需要像上面那樣把引數名稱寫出來;但如果你需要略過其中幾個,就必須為你略過的第一個之後的引數命名。

greeting("John Doe", add_exclamation=true)

記憶體管理

在這個練習中,你會實作一個程序,這個程序負責配置它回傳的字串。釋放這個字串則是程序呼叫者的責任。

// The procedure will be called like that:
str := two_fer("Alice")
// ...
// and eventually the caller will delete the string
delete(str)

你可能也會想看看 Odin 官方文件中關於預設引數與具名引數的說明。


出處

探索這道練習的來源。

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

準備好開始 Two Fer 了嗎?

註冊 Exercism,透過 73 個練習 和真人引導來學習並精通 Odin,全部免費。