Question on RefValue

You got it right in your first post: in an (immutable) struct, the field iter::Int64 can be 0 or any other Int64. But afterwards you cannot replace it by another. On the other hand, if the field is mutable (e.g. the first field of the example in the video, T::Array{Float64, 2}) you cannot replace it either, but you can mutate it. For instance, if you have:

struct Foo
    i::Int64
    a::Array{Int64, 2}
end

f = Foo(0, [1 2; 3 4])

Then you cannot do f.i = 1 or f.a = [5 6; 7 8]. But you can do f.a[1] = 0, because that is mutating the object referred to by the field a, not replacing it by another object. And you could also mutate it such that it looks as if you were actually replacing it too (watch the dot before the equal sign!):

f.a .= [5 6; 7 8]

Now, a RefValue is, roughly speaking, as a “one-slot” array, which cannot have more than one item of the specified type. That’s why it is indexed more or less as an array (but without any index between the brackets, because it would be superfluous). If iter is a RefValue, then iter[] means “the value that it contains”; iter[] = 1 means “mutate iter inserting 1 in its slot”; and as @jling told, iter[] += 1 is the same as iter[] = iter[] + 1.

8 Likes