具有多个功能输出的Julia内存重用

Tod*_*odd 0 memory-management julia

您可以按如下方式重用阵列内存

> a=[1,2,3];b=a;a=[1,2,3];is(a,b)
false

> a=[1,2,3];b=a;a.=[1,2,3];is(a,b)
true
Run Code Online (Sandbox Code Playgroud)

在我分配整个阵列时,这是唯一必要的.分配子集时,无论是使用.=还是使用,都将始终使用现有数组=.

当使用具有多个输出的函数时,我遇到了这个问题.例:

> f = () -> ([1,2,3],[4,5,6]);
> a, = f()
([1,2,3],[4,5,6])

> a, .= f()
 ERROR: syntax: invalid identifier name ".="

> (a,) .= f()
ERROR: MethodError: no method matching broadcast!(::Base.#identity,::Tuple{Array{Int64,1}}, ::Tuple{Array{Int64,1},Array{Int64,1}})
Closest candidates are:
  broadcast!{nargs}(::Any, ::AbstractArray{T,N}, ::Any...) at broadcast.jl:169
  broadcast!(::Base.#identity, ::AbstractArray{T,N}, ::Number) at broadcast.jl:19
  broadcast!{T,S,N}(::Base.#identity, ::AbstractArray{T,N}, ::AbstractArray{S,N}) at broadcast.jl:23
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点,而不必a在每次通话时扔掉?

Fen*_*ang 6

a .= f()[1]
Run Code Online (Sandbox Code Playgroud)

诀窍.不过,我要指出,这并不能避免在输出数组分配内存(如也许是你的意图?); 它仍然被分配,然后在将其内容复制到之后最终收集垃圾a.唯一的方法是将a参数传递给变异的f!变体f.

我认为没有很好的语法来分配两个输出.您可以将结果存储f()在临时(此存储不涉及复制,因为它只是对返回的内存进行别名f()):

tmp = f()
a .= tmp[1]
b .= tmp[2]
Run Code Online (Sandbox Code Playgroud)