# Composite types with array type fields

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.)

``````arr = [1,2,3]
a3 = A(arr)
``````

The type of `arr` is not the same as the `m` field, so there must be a conversion, and the result of the conversion is clearly not `===` the original. If you don’t want the conversion, use `arr = Int32[1,2,3]`.

In the first case, you are only comparing the fields, post-conversion.

That was quick, thanks a lot! I had forgotten about type conversion.