@views only affect indexing expressions. So the above is equivalent to
out = 0.1 * view(w, 3, :, :) * state
so you don’t allocate anything in the slicing operation. But both view(w,3,:,:) * state will allocate a completely new array, and multiplication with 0.1 will also allocate a new array. There is also no in-place copying into out going on here.
You have to make your operations in-place, the view only helps with the slicing.
A couple of other remarks:
These pre-allocations have no effect:
state = falses(n)
out = ones(Float64,n)
because you over-write them later (not in-place, just new assignment), so they are wasted. In other words, you re-use the labels state and out, but you don’t re-use the arrays that those labels were applied to.
Also, false(n) is very different from rand([false, true], n). The former creates a BitVector, while the latter makes a vector of Bools.
For a vector of random true/false use either state = rand(Bool, n) or state = Random.bitrand(n). Then, in order to update this vector in-place, write rand!(state).