我有一个元组的一维数组,我需要将其传递给定义为的函数
function f(a::Array{Tuple{Vararg{String}}, 1})
#do some processing
end
每个Tuple可以具有任意数量的String元素,但是数组中所有Tuple的元素数量都相同。例如,数组看起来像[("x1","x2"),("y1","y2")]
或[("x1","x2","x3"),("y1","y2","y3")]
等。因此,为此使用了Vararg {String}。
现在,当我运行f([("x1","x2"),("y1","y2")])
时,它会引发错误
“ MethodError:没有与f(:: Array {Tuple {String,String},1})匹配的方法”
我应该如何修改函数定义以使其起作用?
答案 0 :(得分:4)
之所以得到MethodError
,是因为Tuple{Vararg{T}}
不是具体类型,因为Vararg
的元素数量未指定,并且Julia's type parameters are invariant而不是协变。
即使我们有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
您应该改用以下签名来消除错误
function f(a::Vector{<:Tuple{Vararg{String}}})
# or
function f(a::Vector{T}) where {T <: Tuple{Vararg{String}}
由@crstnbr和@BogumiłKamiński共同建议。这些签名将消除错误,但是,它们不限制Tuple的长度相同。例如,您可以使用以下命令调用这些函数
f([("x1, x2"), ("y1", "y2", "y3"])
由于要确保数组中的元组包含相同数量的元素,因此需要在类型注释中指定此限制。 Vararg
的文档提供了有关如何指定元素数的信息。
Vararg{T,N}
元组类型Tuple的最后一个参数可以是特殊类型Vararg, 表示任意数量的尾随元素。类型
Vararg{T,N}
恰好对应于N
类型的T
元素。Vararg{T}
对应零 或更多类型T
的元素。Vararg
元组类型用于表示 varargs方法接受的参数(请参阅有关Varargs函数的部分 在手册中。)
你可以和
一起去function f(a::Vector{Tuple{Vararg{String, N}}}) where N
...
end
或使用NTuple
的紧凑方式
function f(a::Vector{NTuple{N, String}}) where N
end
这些签名将加强您在问题中想要的限制。
您可能是overly specializing your types。
正如@BogumiłKamiński在评论部分中指出的那样,最好使用AbstractString
类型而不是具体的String
类型。
function f(a::Vector{<:NTuple{N, AbstractString}}) where N
...
end
您也可以考虑使用AbstractVector
而不是Vector
。
答案 1 :(得分:1)
您可以将签名修改为
function f(a::Array{<:Tuple{Vararg{String}}, 1})
#do some processing
end
请注意<:
表示Tuple{Vararg{String}}
的所有子类型都可以。
但是,仅保留类型信息可能会更容易。该功能将具有完全相同的速度。