【问题标题】:Julia: Template functions to accept multiple array typesJulia:接受多种数组类型的模板函数
【发布时间】:2018-08-24 16:58:17
【问题描述】:

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

【问题讨论】:

  • 如果您不知道:您在这里定义的不是普通函数,而是匿名函数。因此,如果您尝试添加新方法,您只会覆盖旧方法。定义普通函数/方法的语法是function foo(x::MyType) .... end。或“单线”版本:foo(...) = ...。有关详细信息,请参阅docs.julialang.org/en/v1/manual/functions

标签: arrays function templates julia type-promotion


【解决方案1】:

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

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

这里的 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: creating a method for Any vector with missing values 以了解如何处理更复杂的子类型化案例。

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 2021-03-29
    • 1970-01-01
    • 2020-08-10
    • 2021-12-21
    • 2015-11-10
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    相关资源
    最近更新 更多