假设我有一个向量
v = Any[1,2,3,4]
我想以这样的方式重新计算它的 eltype
typeof(v) = Vector{Int}
是否可以在无需手动连接 中的每个元素的情况下完成此操作v?
您不能“重新输入”现有的v,只需使用更具体的类型1创建它的副本。
假设您已经(静态地)知道结果类型,您有多种选择。最易读的(和 IMO,惯用的)是
Vector{Int}(v)
Run Code Online (Sandbox Code Playgroud)
这几乎相当于
convert(Vector{Int}, v)
Run Code Online (Sandbox Code Playgroud)
除了如果输入类型已经是目标类型,后者不会复制。或者:
convert.(Int, v)
Run Code Online (Sandbox Code Playgroud)
这肯定也会复制。
如果您不知道“常见类型”是什么,则有多种选择可以获取匹配的类型。通常,typejoin可用于查找最小上限:
mapreduce(typeof, typejoin, v; init=Union{})
Run Code Online (Sandbox Code Playgroud)
结果很可能是抽象的,例如Real对于Ints 和Float64s的数组。因此,对于数字类型,您最好使用promote_type:
mapreduce(typeof, promote_type, v; init=Union{}) # or init=Number
Run Code Online (Sandbox Code Playgroud)
这至少为您Float64提供了混合的Ints 和Float64s。
但是所有这些都不是真正推荐的,因为它可能是脆弱的、令人惊讶的,并且肯定不是类型稳定的。
1对于某些类型的组合,具有兼容的二进制形式,reinterpret将工作并返回具有不同类型的视图,但这仅适用于位类型,而Any不能。转换Any[1,2,3]为Int[1,2,3]复制从根本上是必要的,因为这两个数组在内存中具有不同的布局:前者是指向单独分配的整数对象的指针数组,而后者将Int值内联存储在连续内存中。
如果您不知道输出类型,请考虑使用理解式
\n\nfoo(v) = [x for x in v]\nRun Code Online (Sandbox Code Playgroud)\n\n这在我的计算机上比以下速度快得多identity.(v):
julia> v = Any[1,2,3,4];\n\njulia> @btime foo($v);\n 153.018 ns (2 allocations: 128 bytes)\n\njulia> @btime identity.($v);\n 293.908 ns (5 allocations: 208 bytes)\n\njulia> @btime foo(v) setup=(v=Any[rand(0:9) for _ in 1:1000]);\n 1.331 \xce\xbcs (2 allocations: 7.95 KiB)\n\njulia> @btime identity.(v) setup=(v=Any[rand(0:9) for _ in 1:1000]);\n 25.498 \xce\xbcs (494 allocations: 15.67 KiB)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |