Varargs funktionieren mit optionalen Argumenten

Aug 20 2020

Ich habe ein Skript foo.jlmit einer Funktion, die 4 Argumente annehmen kann, von denen 2 optional sind. Ich kann das leicht machen mit

function bar(a, b, c=1, d=2)
    println(a, b, c, d)
end

bar(ARGS[1], ARGS[2], ARGS[3], ARGS[4])

Ich kann dies mit Argumenten aus dem Terminal mit aufrufen

$:> julia foo.jl 1 2 3 4
1234

Aber wenn ich nur wollte , um die ersten beiden Argumente angeben aund bmit c=1und d=2würde ich nicht in der Lage sein , die Skript aufrufen , mit , $:> julia foo.jl 1 2da das Skript einen Funktionsaufruf mit 2 Argumenten nicht enthält. Eine Problemumgehung besteht darin, die Länge des ARGSeingehenden foo.jlund bedingten Aufrufs zu messen 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

Dies ist jedoch etwas sperrig, wenn über 4 Argumente hinausgegangen wird. Also habe ich versucht, variable Argumente zu verwenden, mit denen ich eine beliebige Anzahl von Argumenten aufrufen kann

function bar(a, b, x...)
    println(a, b, x)
end

bar(ARGS[1], ARGS[2], ARGS[3:end])

Dies auf verschiedene Arten aufrufen

$:> 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"],)

Aber dann weiß ich nicht, wie (oder ob ich in der Lage bin) einen Standard festzulegen, x...wenn dieser nicht im Terminal bereitgestellt wird. So etwas Naives function bar(a, b, x...=(1, 2))funktioniert nicht. Eine Lösung wäre hier, die Variablen innerhalb der Funktion abhängig vom Inhalt oder der Größe von festzulegen x.... Aber ich weiß nicht, ob es einen besseren Weg gibt, dies zu tun.

Daher suche ich nach einer Möglichkeit, eine Funktion mithilfe von Argumenten aus dem Terminal aufzurufen, wobei eine Nummer (in diesem Fall 2) erforderlich ist, während der Rest optional und auf einen Standardwert gesetzt ist.

Antworten

2 PrzemyslawSzufel Aug 20 2020 at 07:12

Vielleicht suchen Sie folgende Funktion:

function flexiargs(a1,a2,a3="3",a4="4",a5="5",a6...)
    println((a1,a2,a3,a4,a5,a6))
end
flexiargs(args::AbstractVector)=flexiargs(args...)

Diese Funktion funktioniert mit einer beliebigen Anzahl von Parametern, sofern mindestens zwei davon vorhanden sind.

Testen wir mit folgenden Daten:

args0=["one","two"]
args1=["one","two","three","four"];
args2=vcat(args,"five","six","seven") 

Mal sehen, wie es funktioniert:

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"))

Beachten Sie schließlich, dass dies auch in Ordnung ist:

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 diesem Fall ist standardmäßig (wenn nicht genügend Werte vorhanden sind args) a6einfach ein Element, Tuplewobei das einzige Element a ist Tuple ("6","7").