朱莉娅未能多次派遣

时间:2017-09-22 14:17:01

标签: 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)

当我这样称呼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 ...

1 个答案:

答案 0 :(得分:6)

是的,Array{UInt8} <: Array{Integer} == false。这称为“参数不变性”。很多其他问题已经讨论过这个话题。

您遇到的另一个问题是,当您使用静态函数参数时 - 即f(…) where T - T 必须匹配某些内容它可以在函数体中使用。这导致Union中出现问题,其中T在每个选项中都不可用。我相信有一个关于更改此行为以允许匹配不包含Union的{​​{1}}元素的公开问题,如果您尝试访问它,则会将该绑定转换为未定义的变量。

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

T