带有可选参数的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

但是,如果我只想用c=1d=2指定前两个参数ab,我将无法用$:> julia foo.jl 1 2调用脚本,因为脚本不包含带2个参数的函数调用。一个解决方案是测量foo.jlARGS的长度,并有条件地调用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(,并提供了良好的控制和可读性。

相关内容

  • 没有找到相关文章

最新更新