Julia:模板函数可以接受多种数组类型

时间:2018-08-24 16:58:17

标签: arrays function templates julia type-promotion

我正在尝试使用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)

1 个答案:

答案 0 :(得分:4)

使用Matrix{<:Number}代替Array{Number, 2}作为类型限制,所有方法都可以使用(Array{<:Number, 2}也可以使用)。

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

此处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手册详细描述了参数类型的子类型在Julia 0.6中的工作方式。然后,我认为您可以查看最近的SO问题Julia: creating a method for Any vector with missing values,以了解如何处理更复杂的子类型案例。