I am trying to understand the strange behavior I see in the code below.
struct A
m::Vector{Int32}
end
struct B
m::Vector{Vector{Int32}}
end
let
# Here, the assigment works like a pointer assigment
a1 = A([1,2,3])
a2 = A(a1.m)
@show a1.m === a2.m
a1.m[1] = 2
@show a1, a2
# Here it performs a copy
arr = [1,2,3]
a3 = A(arr)
@show a3.m === arr
arr[1] = 2
@show arr, a3
# The same thing here
b1 = B([[1,2],[3]])
b2 = B(b1.m)
@show b1.m === b2.m
b1.m[1] = [1]
@show b1, b2
arr = [[1,2],[3]]
b3 = B(arr)
@show b3.m === arr
# and it's a deepcopy
arr[1][1] = 2
@show arr, b3
end
The output I get is
a1.m === a2.m = true
(a1, a2) = (A(Int32[2, 2, 3]), A(Int32[2, 2, 3]))
a3.m === arr = false
(arr, a3) = ([2, 2, 3], A(Int32[1, 2, 3]))
b1.m === b2.m = true
(b1, b2) = (B(Vector{Int32}[[1], [3]]), B(Vector{Int32}[[1], [3]]))
b3.m === arr = false
(arr, b3) = ([[2, 2], [3]], B(Vector{Int32}[[1, 2], [3]]))
I find this really strange. I was hoping to use an immutable struct as a simple container for a few pointers, but it seems that in some cases it performs a deepcopy of the input array. What is the difference between these two cases, how do I know when it’s only the pointer being copied vs. the resource handled by the pointer being copied? (I am assuming that the behavior here extends to mutable type fields in general.)