v06 我想寫一個期望2到3個參數的簽名。第一個是Integer或Integer矢量。第二個是整數矢量或整數矩陣。第三個是整數矢量或未指定。Julia無法多次發送
我第一次嘗試像這樣
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{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 ...
當你有這樣非常複雜的類型簽名,特別是有很多聯合時,它可能是一個標誌,你應該把它分成幾個單獨的方法定義。特別是,你可能希望至少避免使用'foo(a,b,c = Nothing)',而採用'foo(a,b,c)'和'foo(a,b)'。另外,請考慮這些類型之間是否存在關聯,例如,僅當'b'是'Matrix'時'a' a'Vector'? – DNF
@DNF我明白你的關注。問題是,如果我這樣做,用戶得到無用的茱莉亞錯誤消息,而不是我寫的有用的。例如。 「沒有方法存在,你有一個矩陣爲b和c是Void」,我寧願像這樣「如果你指定b作爲矩陣,你必須指定c爲這些維度的向量。事實上,這個簽名是檢查所有內容並將所有內容都轉換爲正確類型後調用真實方法的廢話檢查簽名。 – Nozdrum
您正在設置自己去做大量的顯式輸入檢查,這與多次調度的想法背道而馳。你只是爲了避免讓人們接觸到普通的Julia錯誤信息而造成很大的痛苦。另外,如果我沒有提供任何'c',我會驚訝地發現'c'是'Void'!建議:用正確的簽名將你的功能分解成單獨的方法。然後製作一個後備方法(或多個),以捕獲剩下的部分:'f(a,b,c)= ...'沒有類型,然後讓那個人找出輸入有什麼問題併發出錯誤。 – DNF