我有一种可变的合成型,
mutable struct MyType
x::Array{Float64}
end
我有一个函数我想把它修改到位,
function f(z::MyType)
newx = z.x + 1
z.x = newx
return z
end
这似乎不适用于更新z。我遗漏了什么?
发布于 2018-11-19 15:46:14
z.x
是一个数组,因此必须编写z.x .+ 1
(注意额外的点)来表示元素级的加法。
function f(z::MyType)
newx = z.x .+ 1
z.x = newx
return z
end
此函数确实更新了z
。
julia> z = MyType(rand(1:10, 4))
MyType([10.0, 7.0, 2.0, 2.0])
julia> f(z)
MyType([11.0, 8.0, 3.0, 3.0])
julia> z
MyType([11.0, 8.0, 3.0, 3.0])
julia> @btime f($z);
886.115 ns (4 allocations: 208 bytes)
分配(至少)是从以下事实来理解的:它分配了一个新的数组newx
(每个元素都增加一个的z.x
副本),然后将其设置为分配给z.x
的新数组。以前分配给z.x
的原始数组现在丢失了(并将被gc‘’ed)。
您可能想要做的是修改分配给z.x
就地的数组,而不创建中间数组。这可以通过编写
function f(z::MyType)
z.x .= z.x .+ 1 # or equivalently z.x .+= 1
return z
end
注意.=
,而不是=
,它分配在适当的位置(您可以想到一个元素级的赋值)。这给了我们
julia> @btime f($z);
372.284 ns (2 allocations: 48 bytes)
请注意,您也可以写得更短。
f(z::MyType) = (z.x .+= 1; z)
https://stackoverflow.com/questions/53377438
复制相似问题