V06 我想写一个期望2到3个参数的签名。第一个是Integer或Vector of Integer。第二个是整数向量或整数矩阵。第三个是整数向量或未指定。
我首先尝试过这样的
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 ...
现在我明白了为什么朱莉娅无法匹配这个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}
现在朱莉娅甚至没有告诉我什么不匹配!
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 ...
答案 0 :(得分:6)
是的,Array{UInt8} <: Array{Integer} == false
。这称为“参数不变性”。很多其他问题已经讨论过这个话题。
您遇到的另一个问题是,当您使用静态函数参数时 - 即f(…) where T
- T
必须匹配某些内容它可以在函数体中使用。这导致Union
中出现问题,其中T
在每个选项中都不可用。我相信有一个关于更改此行为以允许匹配不包含Union
的{{1}}元素的公开问题,如果您尝试访问它,则会将该绑定转换为未定义的变量。
现在的解决方法是使用不是函数的静态参数的类型变量。如,
T