【发布时间】:2017-09-23 17:22:16
【问题描述】:
我对参数化方法在 Julia 中的工作方式感到困惑。我也希望参数是在这里使用的正确词。我已阅读有关方法的文档,但仍不清楚为什么会发生以下错误。如果我定义一个函数如下
function Bazinga{T<:Real}(mat ::Union{Array{T,2},SparseMatrixCSC})
mat^4
end
然后运行
Penny = sparse(randn(10,10))
Bazinga(Penny)
我明白了
ERROR: MethodError: `Bazinga` has no method matching Bazinga(::SparseMatrixCSC{Float64,Int64})
Closest candidates are:
Bazinga{T<:Real}(::Union{Array{T<:Real,2},SparseMatrixCSC{Tv,Ti<:Integer}})
但是Int64<:Int 是真的,那么这里的问题是什么?
如果我将函数重新定义为
function Bazinga(mat ::Union{Array{Real,2},SparseMatrixCSC})
mat^4
end
没有产生错误并且该功能有效。现在还有两个函数的方法
Bazinga(mat::Union{Array{Real,2},SparseMatrixCSC{Tv,Ti<:Integer}}) at none:2
Bazinga{T<:Real}(mat::Union{Array{T<:Real,2},SparseMatrixCSC{Tv,Ti<:Integer}}) at none:2
SparseMatrixCSC{Tv,Ti<:Integer} 都在其中,但仅在第一种情况下会导致错误。
欢迎任何输入!
Edit1:为什么Array{Float64,1} <:Array{Real,1} 是假的?
Edit2:Edit1 中的问题由Arrays break string types in Julia 解决。但我认为它不能解释该方法会发生什么。或者至少我没有看到。
【问题讨论】:
-
Bazinga{T<:Real}(mat::Union{Array{T,2},SparseMatrixCSC{T}) = mat^4有效。似乎 Julia 喜欢 union 的所有元素都具有相同的参数“模板”。这可能是一个已知问题,熟悉它的人会回答。 -
很可能,上述问题是因为 Union 选择了 SparseMatrixCSC 分支,然后由于 T 未使用,它无法填充参数 T 并确定与调用匹配的方法。
-
@Dan Getz 这听起来可能是原因。我使用您上面的建议来修复我的代码,非常感谢!我想给你和
@Gnimuc K.,学分,但我怀疑有办法做到这一点