2014-10-19 42 views
10

問題是關於Julia的'最佳實踐'。我已閱讀thisthis。我有一個函數在Julia沒有自然違約的命名參數

function discount_rate(n, fv, pmt, pv; pmt_type = 0) 
... 
end 

現在的問題是我要打電話像這樣

discount_rate(10, 10, 10, -10) 

目前還不清楚是什麼,這些參數的含義的方法 - 即使我忘記了。我喜歡做的是寫

discount_rate(n = 10, fv = 10, pmt = 10, pv = -10) 

這更清晰:更容易閱讀和理解。但我不能通過使這些參數keywords參數或optional參數來定義我的方法,因爲它們沒有自然默認值。從設計的角度來看,有沒有推薦的方法呢?

回答

6

可以做到以下幾點:

function discount_rate(;n=nothing,fv=nothing,pmt=nothing,pv=nothing,pmt_type=0) 
    if n == nothing || fv == nothing || pmt == nothing || pv == nothing 
     error("Must provide all arguments") 
    end 
    discount_rate(n,fv,pmt,pv,pmt_type=pmt_type) 
end 

function discount_rate(n, fv, pmt, pv; pmt_type = 0) 
    #... 
end 
+1

謝謝,伊恩。另外,在Youtube上發現你的Julia視頻教程非常有用。 – vathymut 2014-10-19 16:40:17

0

作爲後續行動,它得到了一個有點乏味有(重新)寫的關鍵字,只對我已經有功能的同行。通過上述伊恩的回答啓發,我寫了一個宏,本質上是做同樣的事情...

macro make_kwargs_only(func, args...) 
quote 
    function $(esc(func))(; args...) 
    func_args = [ arg[2] for arg in args ] 
    return $(esc(func))(func_args...) 
    end 
end 
end 

因此,例如

f(a, b) = a/b 
@show f(1, 2) 
f(1,2) => 0.5 

創建它的關鍵字只對應給出

@make_kwargs_only f a b 
@show f(a = 1, b = 2) 
f(a=1,b=2) => 0.5 

但請注意,這不是一般情況。這裏爭論的順序是至關重要的。理想情況下,我會喜歡這個宏以同樣的方式爲f(a = 1, b = 2)f(b = 2, a = 1)工作。事實並非如此。

@show f(b = 2, a = 1) 
f(b=2,a=1) => 2.0 

就目前而言,作爲一個黑客,我用methods(f),如果我不記得參數的順序。任何有關如何重寫宏來處理這兩種情況的建議是值得歡迎的......也許可以根據函數簽名func在宏的函數定義中對func_args進行排序?