朱莉娅:重新解释的反面是什么?

时间:2019-09-08 08:10:18

标签: julia

我们可以执行以下操作将UInt8的数组转换为UInt64

reinterpret(UInt64, rand(UInt8, 8))

这有逆吗?要将UInt64变成Vector{UInt8}吗?

2 个答案:

答案 0 :(得分:7)

再次重新解释。请记住,即使长度为1,重新解释也会使它的行为像数组一样。

julia> a8 = rand(UInt8, 8)
8-element Array{UInt8,1}:
 0x25
 0xaf
 0x2c
 0x33
 0xca
 0xbe
 0xd8
 0xa6

julia> a64 = reinterpret(UInt64, a8)
1-element reinterpret(UInt64, ::Array{UInt8,1}):
 0xa6d8beca332caf25

julia> a8 = reinterpret(UInt8, a64)
8-element reinterpret(UInt8, reinterpret(UInt64, ::Array{UInt8,1})):
 0x25
 0xaf
 0x2c
 0x33
 0xca
 0xbe
 0xd8
 0xa6

答案 1 :(得分:6)

值得注意的是,reinterpret以两种不同的方式工作。一种是将原始类型重新解释为另一种原始类型,例如reinterpret(Char, 0x00000077)。另一个是将类型T的数组重新解释为另一种类型的数组,如reinterpret(UInt128, [1, 2])中所示。在这两种情况下,这两个操作均不涉及实际更改或复制数据。

如果要询问如何将位类型(如UInt64)转换为数组,那是不同的,因为您实际上需要分配数组,从而复制数据。因此,您不是在“重新解释”现有数据,而是在创建新数据。

您可以使用指针执行此操作:

function to_array(x::UInt64)
    arr = Vector{UInt8}(undef, 8)
    GC.@preserve arr unsafe_store!(Ptr{UInt64}(pointer(arr)), x)
    return arr
end

这是高效的。再次重申,这根本不是重新解释操作。