【问题标题】:Generic Numeric Arrays in JuliaJulia 中的通用数值数组
【发布时间】:2018-10-30 14:53:38
【问题描述】:

我正在尝试通过阅读文档来学习 Julia,他们的代码如下所示:

function testFunction(x::Number)
    return x+5
end

这是一个适用于 Juila 中任何一种数字类型的函数。

但是,如果我尝试做类似的事情,像这样:

function testFunction2(x::Array{Number})
    return x
end

我收到以下错误:

ERROR: MethodError: no method matching testFunction2(::Array{Int64,1})
Closest candidates are:
  testFunction2(::Array{Number,N} where N) at /Users/.../Desktop/Test.jl:45

我做错了吗?我认为:Array{Float64} 是您声明特定类型数组的方式,但使用类似Number 的类型(适用于常规情况)在这里不起作用......任何见解都值得赞赏。

【问题讨论】:

  • testFunction2 应声明为:function testFunction2(x::Array{<:Number})(与 <:),因为 Array{Float64} 不是 Array{Number}。见:Type inheritance in function arguments
  • Julia 的类型系统是不变的。这在this section of the docs 中有详细介绍(特别是,请参阅突出显示的警告)

标签: arrays types julia


【解决方案1】:

添加到另一个答案:手册中的示例与您的代码之间存在行为差异的原因是,在您的情况下,Number 用作另一种类型 (Array) 中的类型参数。与 Number 本身用作类型相比,这会得到更严格的类型检查。正如@StefanKarpinski 在this answer 中所说,

这是 Julia 中参数类型不变性的结果。有关详细信息,请参阅手册中的chapter on types

(链接已更正为当前。)

手册中的关键点是:“即使 Float64 <: real point>Int64 <: Number,我们没有Array{Int64} &lt;: Array{Number},这就是类型匹配失败的原因。

所以一般来说,你可以x::Number来匹配任何数字类型,你可以写p::AbstractString来匹配作为AbstractString子类型的任何字符串类型,等等。但如果你'使用抽象类型作为类型参数作为另一种类型的一部分,那么您必须明确指定您希望它匹配参数类型的所有子类型,即与Point{&lt;:Real}Array{&lt;:Number}

【讨论】:

  • +1,与f(x::Number) 相比,我应该指出参数类型不变性,这将允许f(1)f(2+3im) 等。
【解决方案2】:

定义

function testFunction2(x::Array{Number})
    return x
end

是接受Array{Number} 作为输入的识别函数。所以以下将起作用:

testFunction2(collect((1,3,-2.7,5+2im)))

但这不会起作用:

testFunction2([1,3,7,9])

从这里可以看出:

julia> typeof(collect((1,3,-2.7,5+2im)))
Array{Number,1}

julia> typeof([1,3,7,9])
Array{Int64,1}

第一个匹配x 的类型在您的testFunction2 定义中,第二个不匹配。 (请注意,Array{Number}Array{Number,1} 的同义词。)

您正在寻找的是一个函数,它接受任何元素类型的数组,它是Number 的子类型。这样做是:

function testFunction2(x::Array{T}) where {T<:Number}
    return x
end

现在我们有一个参数T,它可以是Number 的任何子类型。你也可以使用糖

function testFunction2(x::Array{<:Number})
    return x
end

甚至testFunction2(x::Array{&lt;:Number}) = x

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 2016-01-06
    相关资源
    最近更新 更多