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
ранее, теперь потерян (и будет скопирован).
Предположительно, вы хотите изменить массив, назначенный 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)