考虑这样一种情况,我首先使用eltypeofAny增量创建一个 Vector;之后,我想缩小它的元素类型。我怎样才能做到这一点?
julia> vec = Any[1, 2, 3.]
3-element Vector{Any}:
1
2
3.0
Run Code Online (Sandbox Code Playgroud)
I can use something like convert(Vector{Real}, vec). But in this case, I'm specifying the type manually while I want Julia to decide the best suitable eltype for it.
This can be achieved by broadcasting the identity function on each element of the given container (either an Array or a Vector):
julia> narrowed = identity.(vec)
3-element Vector{Real}:
1
2
3.0
Run Code Online (Sandbox Code Playgroud)
Note that this doesn't lead to promoting (or demoting) the type of each individual element of the given container:
julia> typeof(narrowed[1]), typeof(narrowed[3])
(Int64, Float64)
Run Code Online (Sandbox Code Playgroud)
However, in the case of acquainting with related functions in Julia, This can be done verbosely by using the typejoin function to achieve the type join of the container's elements. According to the concise doc of the function:
typejoin(T, S)
Return the closest common ancestor of T and S, i.e. the narrowest type from which they both inherit.
The argument of the typejoin should be a subtype of Core.Type{T} (However, it seems more sensible to define it as typejoin(T...) since it can get an indefinite number of positional arguments, not just two.)
julia> typeof.(vec)
3-element Vector{DataType}:
Int64
Int64
Float64
julia> typejoin(typeof.(vec)...)
Real
julia> convert(Vector{typejoin(typeof.(vec)...)}, vec)
3-element Vector{Real}:
1
2
3.0
Run Code Online (Sandbox Code Playgroud)
小类型联合(例如Union{Int, Float64}在 Julia 中处理速度比抽象类型快得多,因此您应该避免抽象元素的向量,例如Vector{Real}支持具体类型的联合,例如Union{Int, Float64}.
话虽如此,这里有一段代码可以实现这样的联合:
\njulia> Vector{Union{Set(typeof.(vec))...}}(vec)\n3-element Vector{Union{Float64, Int64}}:\n 1\n 2\n 3.0\nRun Code Online (Sandbox Code Playgroud)\n这是一个简单的测试,表明对于 100 个元素的向量,性能差异为 4 倍:
\njulia> a1 = Vector{Union{Int, Float64}}(rand(100));\n\njulia> a2 = Vector{Real}(rand(100));\n\njulia> @btime minimum($a1);\n 428.643 ns (0 allocations: 0 bytes)\n\njulia> @btime minimum($a2);\n 2.000 \xce\xbcs (102 allocations: 1.59 KiB)\nRun Code Online (Sandbox Code Playgroud)\n