Funzione Varargs con argomenti opzionali
Ho uno script foo.jl
con una funzione che può richiedere 4 argomenti, 2 dei quali sono opzionali. Posso farlo facilmente con
function bar(a, b, c=1, d=2)
println(a, b, c, d)
end
bar(ARGS[1], ARGS[2], ARGS[3], ARGS[4])
Posso chiamarlo con argomenti dal terminale con
$:> julia foo.jl 1 2 3 4
1234
Ma se volessi specificare solo i primi due argomenti a
e b
, con c=1
e d=2
, non sarei in grado di chiamare lo script con $:> julia foo.jl 1 2
poiché lo script non contiene una chiamata di funzione con 2 argomenti. Una soluzione è misurare la lunghezza di ARGS
in foo.jl
e chiamare in modo condizionale 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
Ma questo è un po 'ingombrante quando si va oltre i 4 argomenti. Quindi ho esaminato l'uso di argomenti variabili, dove potevo chiamare un numero arbitrario di argomenti con
function bar(a, b, x...)
println(a, b, x)
end
bar(ARGS[1], ARGS[2], ARGS[3:end])
chiamandolo in più modi
$:> 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"],)
Ma poi non so come (o se sono in grado) impostare un valore predefinito per x...
se non è fornito nel terminale. Qualcosa di ingenuo come function bar(a, b, x...=(1, 2))
non funziona. Una soluzione qui sarebbe impostare le variabili all'interno della funzione a seconda del contenuto o della dimensione di x...
. Ma non so se c'è un modo migliore per farlo.
Quindi sto cercando un modo per chiamare una funzione utilizzando gli argomenti dal terminale, dove è richiesto un numero (2 in questo caso), mentre il resto è facoltativo e impostato su un valore predefinito.
Risposte
Forse stai cercando la seguente funzione:
function flexiargs(a1,a2,a3="3",a4="4",a5="5",a6...)
println((a1,a2,a3,a4,a5,a6))
end
flexiargs(args::AbstractVector)=flexiargs(args...)
Questa funzione funzionerà con un numero qualsiasi di parametri a condizione che ce ne siano almeno due.
Proviamo con i seguenti dati:
args0=["one","two"]
args1=["one","two","three","four"];
args2=vcat(args,"five","six","seven")
Vediamo come funziona:
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"))
Infine nota che anche questo va bene:
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...)
In tal caso, per impostazione predefinita (se non sono presenti valori sufficienti args
) a6
sarà semplicemente un elemento Tuple
con l'unico elemento a Tuple
("6","7")
.