如何在Julia中重新计算向量的eltype

如何在Julia中重新计算向量的eltype,julia,Julia,假设我有一个向量 v=任何[1,2,3,4] 我想以这样的方式重新计算它的eltype typeof(v)=向量{Int} 不必手动连接v中的每个元素就可以实现这一点吗?您不能“重新键入”现有的v,只需创建一个具有更具体类型1的副本即可 转化 假设您已经(静态地)知道结果类型,那么您有多个选项。最具可读性(在我看来,是惯用的)是 这几乎相当于 convert(Vector{Int}, v) 但如果输入类型已经是目标类型,则后者不会复制。或者: convert.(Int, v) 当然也会复制

假设我有一个向量
v=任何[1,2,3,4]

我想以这样的方式重新计算它的eltype
typeof(v)=向量{Int}

不必手动连接
v
中的每个元素就可以实现这一点吗?

您不能“重新键入”现有的
v
,只需创建一个具有更具体类型1的副本即可

转化 假设您已经(静态地)知道结果类型,那么您有多个选项。最具可读性(在我看来,是惯用的)是

这几乎相当于

convert(Vector{Int}, v)
但如果输入类型已经是目标类型,则后者不会复制。或者:

convert.(Int, v)
当然也会复制

转换成什么 如果您不知道“公共类型”是什么,那么有多个选项可以选择如何获得匹配的类型。通常,可用于查找最小上界:

mapreduce(typeof, typejoin, v; init=Union{})
结果很可能是抽象的,例如,对于
Int
s和
Float64
s的数组,
Real
。因此,对于数字类型,您最好使用:

这至少为混合
Int
s和
Float64
s提供了
Float64

但所有这些都不是真正推荐的,因为它可能是脆弱的,令人惊讶的,并且肯定不是类型稳定的



1对于具有兼容二进制格式的某些类型组合,将工作并返回具有不同类型的视图,但这仅适用于bits类型,而
Any
则不适用。要将
任何[1,2,3]
转换为
Int[1,2,3]
基本上需要复制,因为这两个数组在内存中具有不同的布局:前者是指向单独分配的整数对象的指针数组,后者将
Int
值内联存储在连续内存中。

这是一个快速而肮脏的技巧,通常可以解决问题

julia> v = Any[1,2,3,4]
4-element Array{Any,1}:
 1
 2
 3
 4

julia> identity.(v)
4-element Array{Int64,1}:
 1
 2
 3
 4

如果你不知道输出类型,那么考虑使用一个理解< /P>

foo(v) = [x for x in v]
这在我的计算机上比身份识别快得多。(v):


感谢Stefan的编辑,我认为这是理所当然的。一个小小的评论是,
Vector{Int}(x)
将始终复制
x
,而
convert(Vector{Int},x)
如果
x
已经具有要转换的类型,则不会复制。
julia> v = Any[1,2,3,4]
4-element Array{Any,1}:
 1
 2
 3
 4

julia> identity.(v)
4-element Array{Int64,1}:
 1
 2
 3
 4
foo(v) = [x for x in v]
julia> v = Any[1,2,3,4];

julia> @btime foo($v);
  153.018 ns (2 allocations: 128 bytes)

julia> @btime identity.($v);
  293.908 ns (5 allocations: 208 bytes)

julia> @btime foo(v) setup=(v=Any[rand(0:9) for _ in 1:1000]);
  1.331 μs (2 allocations: 7.95 KiB)

julia> @btime identity.(v) setup=(v=Any[rand(0:9) for _ in 1:1000]);
  25.498 μs (494 allocations: 15.67 KiB)