オプションの引数を持つ可変引数関数

Aug 20 2020

foo.jl4つの引数を取ることができる関数を持つスクリプトがあります。そのうちの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

ただし、最初の2つの引数ab、withc=1d=2、のみを指定したい場合$:> julia foo.jl 1 2、スクリプトには2つの引数を持つ関数呼び出しが含まれていないため、でスクリプトを呼び出すことはできません。回避策は、ARGSinの長さを測定し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)が必要ですが、残りはオプションであり、デフォルトに設定されています。

回答

2 PrzemyslawSzufel Aug 20 2020 at 07:12

おそらくあなたは次の関数を探しています:

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

この関数は、少なくとも2つのパラメーターがあれば、任意の数のパラメーターで機能します。

次のデータでテストしてみましょう。

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

その場合、デフォルトでは(十分な値が含まれていない場合argsa6、要素は1つだけで、は1つの要素TupleになりTuple ("6","7")ます。