Julia未能进行多次调度
v06 我想写一个期望2到3个参数的签名。第一个是整数或整数向量。第二个是整数向量或整数矩阵。第三个是整数向量或未指定 我第一次是这样试的Julia未能进行多次调度,julia,Julia,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])时,我得到一个错误,告诉我它无法匹配
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{UInt8}当你有这样非常复杂的类型签名,特别是有很多联合时,这可能是一个信号,你应该把它分成几个单独的方法定义。特别是,您可能希望至少避免使用foo(a,b,c=nothing)
,而使用foo(a,b,c)
和foo(a,b)
。此外,考虑类型之间是否存在连接,例如,是<代码> A<代码> A<代码>向量< /代码>,只有当<代码> b>代码>是<代码>矩阵< /代码>?@ DNF时,我理解您的关注。问题是,如果我这样做,用户会收到无用的错误消息,而不是我编写的有用消息。例如,“没有一种方法存在于b的矩阵中,而c是无效的”,我宁愿这样说“如果你指定b为矩阵,你必须指定c为这些维度的向量”。事实上,这个签名是一个狗屁的检查签名,它在检查所有内容并将所有内容转换为正确的类型后调用real方法。您正在设置自己进行大量显式输入检查,这与多次分派的思想背道而驰。为了避免让人们暴露在普通的错误消息中,你给自己带来了很多痛苦。另外,如果我没有提供任何c
,我会惊讶地被告知c
是Void
!建议:将函数拆分为具有正确签名的单独方法。然后创建一个(或多个)回退方法来捕获其余部分:f(a,b,c)=……
不带类型,让该方法找出输入的错误并发出错误。不确定您想要什么,但类似于:foo(a::Integer,b::Vector){对于我目前的问题,我不认为这样做有什么好处。我不相信这会使我的代码更可读。IIRC,在过去不支持三角分派的时候,我们必须定义一个typealias
来解决这个问题,例如typealias IntVector{T
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 ...
foo(a::Union{Integer, Vector{<:Integer}},
b::Union{Vector{<:Integer}, Matrix{<:Integer}},
c::Union{Void, Vector{<:Integer}} = nothing) = 1