2014-10-19 35 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进行排序?