Функция Varargs с необязательными аргументами
У меня есть сценарий foo.jl
с функцией, которая может принимать 4 аргумента, 2 из которых являются необязательными. Я могу легко сделать это с
function bar(a, b, c=1, d=2)
println(a, b, c, d)
end
bar(ARGS[1], ARGS[2], ARGS[3], ARGS[4])
Я могу вызвать это аргументами из терминала с помощью
$:> julia foo.jl 1 2 3 4
1234
Но если бы я хотел указать только первые два аргумента a
и b
с помощью c=1
и d=2
, я бы не смог вызвать сценарий с помощью, $:> julia foo.jl 1 2
поскольку сценарий не содержит вызова функции с двумя аргументами. Обходной способ - измерить длину ARGS
in foo.jl
и условно вызвать bar
:
if length(ARGS) == 2
bar(ARGS[1], ARGS[2])
elseif length(ARGS) == 3
bar(ARGS[1], ARGS[2], ARGS[3])
else
bar(ARGS[1], ARGS[2], ARGS[3], ARGS[4])
end
Но если выйти за рамки 4 аргументов, это немного громоздко. Итак, я рассмотрел использование переменных аргументов, где я мог бы вызвать произвольное количество аргументов с помощью
function bar(a, b, x...)
println(a, b, x)
end
bar(ARGS[1], ARGS[2], ARGS[3:end])
называя это несколькими способами
$:> julia foo.jl 1 2 12(String[],) $:> julia foo.jl 1 2 3 4
12(["3", "4"],)
$:> julia foo.jl 1 2 3 4 5 6
12(["3", "4", "5", "6"],)
Но тогда я не знаю, как (или могу) установить значение по умолчанию, x...
если оно не предусмотрено в терминале. Что-то наивное вроде function bar(a, b, x...=(1, 2))
не работает. Решением здесь было бы установить переменные внутри функции в зависимости от содержимого или размера x...
. Но я не знаю, есть ли лучший способ сделать это.
Итак, я ищу способ вызвать функцию с использованием аргументов из терминала, где требуется число (в данном случае 2), а остальные являются необязательными и установлены по умолчанию.
Ответы
Возможно, вы ищете следующую функцию:
function flexiargs(a1,a2,a3="3",a4="4",a5="5",a6...)
println((a1,a2,a3,a4,a5,a6))
end
flexiargs(args::AbstractVector)=flexiargs(args...)
Эта функция будет работать с любым количеством параметров при условии, что их как минимум два.
Давайте протестируем со следующими данными:
args0=["one","two"]
args1=["one","two","three","four"];
args2=vcat(args,"five","six","seven")
Посмотрим, как это работает:
julia> flexiargs(args0)
("one", "two", "3", "4", "5", ())
julia> flexiargs(args1)
("one", "two", "three", "four", "5", ())
julia> flexiargs(args2)
("one", "two", "three", "four", "five", ("six", "seven"))
Наконец, обратите внимание, что это тоже нормально:
function flexiargs(a1,a2,a3="3",a4="4",a5="5",a6...=("6","7"))
println((a1,a2,a3,a4,a5,a6))
end
flexiargs(args::AbstractVector)=flexiargs(args...)
В этом случае по умолчанию (если в нем недостаточно значений args
) a6
будет просто один элемент Tuple
с единственным элементом Tuple
("6","7")
.