我有一个一维元组数组,我需要将其传递给定义为的函数
function f(a::Array{Tuple{Vararg{String}}, 1})
#do some processing
end
Run Code Online (Sandbox Code Playgroud)
每个元组可以有任意数量的字符串元素,但对于数组中的所有元组,元素的数量将相同。例如,该阵列可以看起来像[("x1","x2"),("y1","y2")]或[("x1","x2","x3"),("y1","y2","y3")]等等。因此VARARG {字符串}的这个用法。
现在,当我运行时f([("x1","x2"),("y1","y2")]),它会引发错误
“方法错误:没有方法匹配 f(::Array{Tuple{String,String},1})”
我应该如何修改函数定义以使其有效?
你得到这个MethodError是因为Tuple{Vararg{T}}它不是一个具体的类型,因为元素的数量Vararg没有指定,并且Julia 的类型参数是不变的而不是协变的。
即使我们有Tuple{Vararg{String, 5}} <: Tuple{Vararg{String}},我们也没有Vector{Tuple{Vararg{String, 5}}} <: Vector{Tuple{Vararg{String}}}
julia> Tuple{Vararg{String, 5}} <: Tuple{Vararg{String}}
true
julia> Vector{Tuple{Vararg{String, 5}}} <: Vector{Tuple{Vararg{String}}}
false
Run Code Online (Sandbox Code Playgroud)
您应该改用以下签名来消除错误
function f(a::Vector{<:Tuple{Vararg{String}}})
# or
function f(a::Vector{T}) where {T <: Tuple{Vararg{String}}
Run Code Online (Sandbox Code Playgroud)
正如@crstnbr 和@Bogumi?Kami?ski 所建议的那样。这些签名将消除错误,但是,它们不限制元组的长度相同。例如,您可以调用这些函数
f([("x1, x2"), ("y1", "y2", "y3"])
Run Code Online (Sandbox Code Playgroud)
由于要确保数组中的元组包含相同数量的元素,因此需要在类型注释中指定此限制。的文档Vararg提供了有关如何指定元素数量的信息。
Vararg{T,N}元组类型 Tuple 的最后一个参数可以是特殊类型 Vararg,它表示任意数量的尾随元素。该类型
Vararg{T,N}与Ntype 的元素完全对应T。Vararg{T}对应于零个或多个类型的元素T。Vararg元组类型用于表示可变参数方法接受的参数(请参阅手册中有关可变参数函数的部分。)
你可以去
function f(a::Vector{Tuple{Vararg{String, N}}}) where N
...
end
Run Code Online (Sandbox Code Playgroud)
或使用紧凑的方式NTuple代替
function f(a::Vector{NTuple{N, String}}) where N
end
Run Code Online (Sandbox Code Playgroud)
这些签名将强制执行您在问题中想要的限制。
您可能过于专业化您的类型。
作为@Bogumi?Kami?ski 在评论部分指出,最好使用AbstractString类型而不是具体String类型。
function f(a::Vector{<:NTuple{N, AbstractString}}) where N
...
end
Run Code Online (Sandbox Code Playgroud)
您也可以考虑使用AbstractVector代替Vector, 。