v06 我想编写一个需要2到3个参数的签名。第一个参数可以是整数或整数向量,第二个参数可以是整数向量或整数矩阵。第三个参数可以是整数向量或未指定。
我首先尝试了以下方式:
function foo(
a::Union{Integer, Vector{Integer}},
b::Union{Vector{Integer}, Matrix{Integer}},
c::Union{Void, Vector{Integer}} = nothing)
当我像这样调用
foo(3, [0o7, 0o5])
时,我会收到一个错误提示,告诉我无法匹配。ERROR: LoadError: MethodError: no method matching foo(::Int64, ::Array{UInt8,1})
Closest candidates are:
foo(::Union{Array{Integer,1}, Integer}, !Matched::Union{Array{Integer,1}, Array{Integer,2}}) at ...
foo(::Union{Array{Integer,1}, Integer}, !Matched::Union{Array{Integer,1}, Array{Integer,2}}, !Matched::Union{Array{Integer,1}, Void}) at ...
现在我明白为什么 julia 无法匹配这个
Array{UInt8} <: Array{Integer} == false
,但这似乎并不太聪明。然后我尝试了这个:
foo(a::Union{Z1, Vector{Z1}},
b::Union{Vector{Z2}, Matrix{Z2}},
c::Union{Void, Vector{Z3}} = nothing
) where {Z1 <: Integer, Z2 <: Integer, Z3 <: Integer}
现在julia甚至不告诉我哪里不匹配了!
ERROR: LoadError: MethodError: no method matching foo(::Int64, ::Array{UInt8,1}, ::Void)
Closest candidates are:
foo(::Union{Array{Z1<:Integer,1}, Z1<:Integer}, ::Union{Array{Z2<:Integer,1}, Array{Z2<:Integer,2}}, ::Union{Array{Z3<:Integer,1}, Void}) where {Z1<:Integer, Z2<:Integer, Z3<:Integer} at ...
foo(::Union{Array{Z1<:Integer,1}, Z1<:Integer}, ::Union{Array{Z2<:Integer,1}, Array{Z2<:Integer,2}}) where {Z1<:Integer, Z2<:Integer} at ...
foo(a, b, c=nothing)
,而更喜欢foo(a, b, c)
和foo(a, b)
。此外,请考虑类型之间是否存在联系,例如,当b
是Matrix
时,a
是否仅为Vector
? - DNFfoo(a::Integer, b::Vector{<:Integer}) = ... end
foo(a::Vector{<:Integer}, b::Matrix{<:Integer}, c::Vector{<:Integer}) = ... end
foo(a::Integer, b...) = error("如果a是整数,则b必须为整数向量。") end
foo(a::Vector{<:Integer}, b...) = error("如果a是整数向量,则b必须为整数矩阵,c必须为整数向量...") end
我认为这实际上会更容易编写好的错误消息。 - DNF