我有一个数组a
,我需要浅层复制到数组b
。
我应该使用
b = collect(a)
或
b = Array(a)
哪个是使用其中一个的差异?
答案 0 :(得分:6)
copy
正是您所寻找的:b = copy(a)
。
实际上,您也可以使用collect
或Array
来完成这项工作,但有什么区别?在朱莉娅,有许多方便的帮助函数/宏可以用来挖掘幕后发生的事情。
@which
,@edit
或@less
经常用于确定源代码中调用的方法:
julia> a = rand(3,3)
julia> @which collect(a)
collect(itr) at array.jl:273
julia> @which Array(a)
(::Type{T}){T}(arg) at sysimg.jl:53
julia> @less collect(a)
collect(itr) = _collect(1:1 #= Array =#, itr, iteratoreltype(itr), iteratorsize(itr))
...
...
julia> @less Array(a)
(::Type{T}){T}(arg) = convert(T, arg)::T
...
...
这里代码告诉collect
将a
(一个数组)视为迭代器,然后做一些迭代器操作的东西,而不只是浅拷贝。如果您想进一步深入研究代码,我建议使用Julia的调试包Gallium.jl
。 Array(a)
刚刚进行了比collect
更好的转换,但也没有必要。 copy
的代码实际上非常低级:
copy{T<:Array}(a::T) = ccall(:jl_array_copy, Ref{T}, (Any,), a)
另一个强大的工具是@code_xxx
宏:
julia> @code_
@code_llvm @code_lowered @code_native @code_typed @code_warntype
例如,您可以检索并比较LLVM-IR代码以观察差异:
julia> @code_llvm Array(a)
define %jl_value_t* @julia_Type_73446(%jl_value_t*, %jl_value_t**, i32) #0 {
top:
%3 = alloca %jl_value_t**, align 8
store volatile %jl_value_t** %1, %jl_value_t*** %3, align 8
%4 = load %jl_value_t*, %jl_value_t** %1, align 8
ret %jl_value_t* %4
}
julia> @code_llvm copy(a)
define %jl_value_t* @julia_copy_73507(%jl_value_t*) #0 {
top:
%1 = call %jl_value_t* inttoptr (i64 4478340144 to %jl_value_t* (%jl_value_t*)*)(%jl_value_t* %0)
ret %jl_value_t* %1
}
@code_llvm collect(a)
将返回一堆代码,因为它不仅仅是一个简单的副本。我不熟悉LLVM,所以我不能说太多。
答案 1 :(得分:3)
copy 是正确的!
help?> copy
search: copy copy! copysign deepcopy unsafe_copy! cospi complex Complex Complex64 Complex32 Complex128 CompositeException
copy(x)
Create a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an array
produces a new array with identically-same elements as the original.