朱莉娅未能多次派遣

Noz*_*rum 3 julia

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)
Run Code Online (Sandbox Code Playgroud)

当我这样称呼这个时,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 ...
Run Code Online (Sandbox Code Playgroud)

现在我明白了为什么朱莉娅无法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}
Run Code Online (Sandbox Code Playgroud)

现在朱莉娅甚至没有告诉我什么不匹配!

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 ...
Run Code Online (Sandbox Code Playgroud)

Mat*_* B. 6

是的,Array{UInt8} <: Array{Integer} == false.这称为"参数不变性".许多其他问题已经讨论过这个主题.

但是,您遇到的另一个问题是,当您使用静态函数参数时 - 也就是说,f(…) where T- T 必须匹配某些东西,因为它可以在函数体中使用.这会导致麻烦UnionS其中,T在每一个选项不可用.我相信有一个关于更改此行为以允许匹配Union不包含的元素的公开问题T,如果您尝试访问它,则会将该绑定转换为未定义的变量.

现在的解决方法是使用不是函数的静态参数的类型变量.例如,

   foo(a::Union{Integer, Vector{<:Integer}},
       b::Union{Vector{<:Integer}, Matrix{<:Integer}},
       c::Union{Void, Vector{<:Integer}} = nothing) = 1
Run Code Online (Sandbox Code Playgroud)