如何在Julia中定义任何浮点类型的数组? [英] How to define an array of any float type in Julia?
问题描述
我尝试了Array{AbstractFloat,1}
,但这不能工作,因为Array{Float64,1} <: Array{AbstractFloat,1}
是false
,即使Float64 <: AbstractFloat
是true
.
I tried Array{AbstractFloat,1}
, but this does not work as Array{Float64,1} <: Array{AbstractFloat,1}
is false
, even though Float64 <: AbstractFloat
is true
.
推荐答案
如果您想要一个可以包含任何浮点值的向量,则正确的类型是Vector{AbstractFloat}
,可以这样构造:
If you want an vector which can contain any kind of floating-point value, then the correct type is Vector{AbstractFloat}
, which can be constructed like this:
julia> v = AbstractFloat[]
AbstractFloat[]
julia> push!(v, 1.5)
1-element Vector{AbstractFloat}:
1.5
julia> push!(v, big(2.0)^1000)
2-element Vector{AbstractFloat}:
1.5
1.071508607186267320948425049060001810561404811705533607443750388370351051124936e+301
julia> map(typeof, v)
2-element Vector{DataType}:
Float64
BigFloat
julia> push!(v, "oy, I'm not a float!")
ERROR: MethodError: Cannot `convert` an object of type String to an object
您正确地认为Vector{Float64}
不是Vector{AbstractFloat}
的子类型.这是因为Julia中参数类型的子类型化是不变的(不是协变,甚至不是协变).更一般地说,没有任何具体类型是任何其他具体类型的子类型,并且Vector{Float64}
和Vector{AbstractFloat}
都是具体类型,因为它们是实际对象的类型:
You are correct that Vector{Float64}
is not a subtype of Vector{AbstractFloat}
. This is because subtyping of parametric types in Julia is invariant (not covariant or even contravariant). Even more generally, no concrete type is a subtype of any other concrete type and Vector{Float64}
and Vector{AbstractFloat}
are both concrete types since they are the types of actual objects:
julia> typeof(v)
Vector{AbstractFloat} = Array{AbstractFloat,1}
julia> typeof([1.5])
Vector{Float64} = Array{Float64,1}
如果您想要一个包含这些具体类型以及浮点值的任何其他向量的抽象类型,可以将其表示为Vector{<:AbstractFloat}
:
If you want an abstract type which includes both of these concrete types as well as any other vector of floating-point values, that can be expressed as Vector{<:AbstractFloat}
:
julia> Vector{AbstractFloat} <: Vector{<:AbstractFloat}
true
julia> Vector{Float64} <: Vector{<:AbstractFloat}
true
julia> Vector{Union{Float64, BigFloat}} <: Vector{<:AbstractFloat}
true
julia> Vector{String} <: Vector{<:AbstractFloat}
false
但是,这种类型是抽象的,您不能创建它的实例.但是,您可以将其用于调度,并编写一种适用于任何浮点值向量的方法:
However, this type is abstract and you cannot create an instance of it. You can, however, use it for dispatch and write a method that will apply to any vector of floating-point values:
f(v::Vector{<:AbstractFloat}) = "a vector of floats"
f(v::Vector) = "a vector but not of floats"
f(x::Any) = "not a vector at all"
此功能在起作用:
julia> f(v)
"a vector of floats"
julia> f([1.5])
"a vector of floats"
julia> f(Union{Float64,BigFloat}[1.5, big(2.0)])
"a vector of floats"
julia> f([1, 2, 3])
"a vector but not of floats"
julia> f("nope")
"not a vector at all"
简而言之,向量的元素类型必须是实际的类型,例如Float64
或AbstractFloat
.您可以将所有浮点向量的类型集合表示为Vector{<:AbstractFloat}
,但这不能是任何向量的类型,因为<:AbstractFloat
不是类型,它是类型的上限.但是,您可以使用Vector{<:AbstractFloat}
定义可对任何浮点矢量进行操作的方法,而与特定的元素类型无关(只要元素类型是某种浮点).
In short, the element type of a vector has to be an actual type, such as Float64
or AbstractFloat
. You can expess the set of types of all floating-point vectors as Vector{<:AbstractFloat}
but this cannot be the type of any vector because <:AbstractFloat
is not a type, it's an upper bound on types. You can, however, use Vector{<:AbstractFloat}
to define methods which operate on any vector of floats, regardless of specific element type (as long as the element type is some kind of float).
这篇关于如何在Julia中定义任何浮点类型的数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!