我有一个可变的复合类型,
mutable struct MyType
x::Array{Float64}
end
我有一个要修改的功能,
function f(z::MyType)
newx = z.x + 1
z.x = newx
return z
end
这似乎不适用于更新z。我想念什么?
答案 0 :(得分:4)
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化)。
您大概想要做的是就地修改分配给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)