2014-10-19 1 views
10

Вопрос о «лучшей практике» в Джулии. Я прочитал this и this. У меня есть функцияИменованные аргументы без естественных дефолтов в Юлии

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

Спасибо, Иэн. Кроме того, вы нашли, что ваши видеоуроки Julia на Youtube очень полезны. – vathymut

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_args в определении функции макроса на основе сигнатуры функции func?