0

我试图在使用该Array类型时保持代码可重用性,但不确定如何在不允许“非法”类型通过的情况下继续进行。示例功能:

foo = function(x::Array{Number,2})
    print(x)
end

foo([1 2 3; 4 5 6; 7 8 9])
# 15

foo([1 2 3])
# MethodError: no method matching (::Array{Int64,1})
# Closest candidate is (::Array{Number,2})

foo(["alpha" "beta"; "pi" "rho"])
# MethodError: no method matching (::Array{String,2})
# Closest candidate is (::Array{Number,2})

然而,第一个例子虽然理论上是一个有效的促销,但foo([1 2 3; 4 5 6; 7 8 9])还是回来了。我不想为每个函数调用手动转换;我也不想必须将所有数组都声明为该类型。我知道我可以将函数调用替换为:MethodError: no method matching (::Array{Int64,2})(::Array{Number,2})Array{Number,2}

foo = function(x::Array)
    print(x)
end

但是,这允许任何维度和类型的数组进入函数。我能想到的唯一其他选择是在我最初允许任何和所有数组的地方添加样板代码,手动检查它们的类型和大小,然后从那里开始,但这感觉不优雅。

有什么建议么?提前致谢。(注意:我使用的是 Julia 0.6.3)

4

1 回答 1

4

使用Matrix{<:Number}而不是Array{Number, 2}作为类型限制,所有都可以工作(也Array{<:Number, 2}可以)。

简而言之Matrix{Int64},不是Matrix{Number}的子类型,而是Matrix{T} where {T<:Number}可以表示为Matrix{<:Number}好像您没有T在函数体中使用的子类型。

Julia 手册在这里https://docs.julialang.org/en/v0.6.4/manual/types/#Parametric-Abstract-Types-1和这里https://docs.julialang.org/en/v0.6.4/ manual/methods/#Parametric-Methods-1详细描述了参数类型中的子类型化在 Julia 0.6 中是如何工作的。然后我认为您可以查看最近的 SO 问题Julia:create a method for Any vector with missing values以了解如何处理更复杂的子类型化案例。

于 2018-08-24T17:08:20.590 回答