我有一个脚本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
但是,如果我只想用c=1
和d=2
指定前两个参数a
和b
,我将无法用$:> julia foo.jl 1 2
调用脚本,因为脚本不包含带2个参数的函数调用。一个解决方案是测量foo.jl
中ARGS
的长度,并有条件地调用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")
。
您可以为x...
提供默认值,如下所示:
function bar(a, b, x::Vararg{Any,N}=(1,2)...) where {N}
println(a, b, x)
end
bar(ARGS[1], ARGS[2], ARGS[3:end]...)
当调用bar
时,重要的是写入ARGS[3:end]...
而不是ARGS[3:end]
。这些点导致一个空数组被计算为零个附加参数。只有在这种情况下,才会使用默认值。
进一步考虑
请注意,x::Vararg{Any,N}
与x...
相同,但允许您使用类型约束。例如,由于ARGS
是一个String数组,您可能希望通过将默认值更改为x::Vararg{String,N}=("1","2")...
来提高函数的类型稳定性。Julia手册中提供了有关Vararg
机构的更多详细信息。
替代解决方案:ArgParse
在处理ARGS
时,我建议使用ArgParse包。它为您提供了命令行文档(julia foo.jl --help
(,并提供了良好的控制和可读性。