2017-01-15 30 views
2

我需要將某些選項傳遞給方法,其中一些選項是可選的(類似於JS中的Object destructuring)。Crystal:方法選項的好方法

我當前的代碼:

def initialize(arg1 : String, options = {} of Symbol => String) 
    opt = MyClass.get_option options, :opt1 
    @opt1 = !opt.empty? ? opt : "Def value" 
    opt = MyClass.get_option options, :opt2 
    @opt2 = !opt.empty? ? opt : "False" 
    # ... 
end 
def self.get_option(options, key : Symbol) 
    (options && options[key]?) ? options[key].strip : "" 
end 

,我把它叫做:MyClass.new "Arg", { opt2: "True", opt4: "123" }

它的工作原理,但我在尋找一種更好的方式。設置每個選項的類型並直接在函數簽名中設置默認值將會很有用。

使用NamedTuple似乎是一個不錯的方式,但我曾與可選值的問題 - options : NamedTuple(opt1: String, opt2: Bool, opt3: String, opt4: Int) | Nil = nil

的另一種方式,我試圖與一個結構,但它似乎使局勢複雜化。

回答

2

Crystal具有可選的命名方法參數作爲核心語言功能,並且不需要編寫用於處理參數的特殊代碼。請參閱有關Method arguments的官方文檔。尤其是,這裏有一個例子:

def method(arg1 : String, *, opt1 = "Def value", opt2 = false) 

並不總是需要的星號,它只是確保以下可選參數可以可以通過名稱傳遞:

method("test", opt1: "other value", opt2: false) 
+0

我並不想模仿他人的朗格模式。簡單地說,我正在尋找一種很好的方式來傳遞選項,我正在學習語言 – Mat

+2

您不會在Crystal中傳遞選項的散列。這在Ruby中可能非常常見,但在Crystal中(或者通常在任何靜態類型語言中),您將很難做到這一點。一種選擇是定義一個具有默認值的結構,並讓用戶傳遞一個只有一些字段是自定義的結構。 – asterite

+0

@asterite:好點,我習慣於Ruby,有時我傾向於用Ruby思考 – Mat