朱莉娅未能多次派遣 [英] Julia fails to multiple dispatch

查看:91
本文介绍了朱莉娅未能多次派遣的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

v06 我想写一个签名,期望2到3个参数.第一个是整数或整数向量.第二个是整数向量或整数矩阵.第三个是整数向量或未指定.

v06 I want to write a signature that expect 2 to 3 arguments. The first one is either an Integer or Vector of Integer. The second one is either a Vector of Integer or Matrix of Integer. The third one is either a Vector of Integer or not specified.

我首先这样尝试过

function foo(
a::Union{Integer, Vector{Integer}},
b::Union{Vector{Integer}, Matrix{Integer}},
c::Union{Void, Vector{Integer}} = nothing)

当我这样称呼foo(3, [0o7, 0o5])时,我收到一条错误消息,提示它无法匹配.

When I call this like this foo(3, [0o7, 0o5]) I get an error telling me that it is unable to match.

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,但是这似乎对茱莉亚并不明智.

Now I understand why julia is unable to match this Array{UInt8} <: Array{Integer} == false, but this just seems to be not smart of julia.

然后我尝试了

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}

现在茱莉亚甚至不告诉我什么不匹配!

Now julia does not even tell me what does not match!

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 ...

推荐答案

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

Yes, Array{UInt8} <: Array{Integer} == false. This is called "parametric invariance." Lots of other questions have discussed this topic.

但是,您遇到的另一个问题是,当您使用静态函数参数(即f(…) where T)时,T 必须匹配某些东西,因为它可以使用在功能的主体中.这会导致Union中的问题,其中T并非在每个选项中都可用.我认为,更改此行为以允许匹配不包含TUnion元素存在一个未解决的问题,如果您尝试访问它,该绑定将变成未定义的变量.

The other problem you're running into, though, is that when you use a static function parameter — that is, f(…) where T — the T must match something since it's available for use in the body of the function. This causes trouble in Unions where T isn't available in every option. I believe there's an open issue about changing this behavior to allow matching Union elements that don't contain T, which would turn that binding into an undefined variable if you tried to access it.

现在的解决方法是使用没有函数的静态参数的var类型.例如,

The workaround right now is to use type vars that aren't static parameters of the function. E.g.,

   foo(a::Union{Integer, Vector{<:Integer}},
       b::Union{Vector{<:Integer}, Matrix{<:Integer}},
       c::Union{Void, Vector{<:Integer}} = nothing) = 1

这篇关于朱莉娅未能多次派遣的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆