The documentation says:
copy(x)
Create a shallow copy of x
: the outer structure is copied, but not all internal values. For example, copying an array produces a new array with identically-same elements as the original.
So if you do b = copy(a)
, then replace an element in b
, a
's contents are unchanged, because it's a different object. If you just did b = a
, they'd both refer to the same array, and any replacement would show up regardless of whether you looked in a
or b
.
Example:
> a = [1, 2]
2-element Array{Int64,1}:
1
2
> b = a
2-element Array{Int64,1}:
1
2
> c = copy(a)
2-element Array{Int64,1}:
1
2
> a[1] = 42
42
> a
2-element Array{Int64,1}:
42
2
> b
2-element Array{Int64,1}:
42
2
> c
2-element Array{Int64,1}:
1
2
>
In the above, a
refers to an array with [1, 2]
in it (to start with). b
is just another variable referring to the same array, but c
is a shallow copy — a different array with (initially) the same elements in it. When we replace the 1
in a[1]
with 42
, we see that replacement whether we look through a
or b
because they're both looking at the same object, but c
is a different object and is unaffected.
In a comment you've asked:
Why does this differ from the chosen answer in the link in my post?
The answer you refer to isn't modifying the top-level array (a
) that we're either assigning to b
(b = a
) or copying (b = copy(a)
). Since it's modifying the contents of an array within it, you see that modification.
Here's a conceptual picture of memory after a = [1, 2]
:
+−−−−−−−−−−−−−+
a−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+
| Index 1: 1 |
| Index 2: 2 |
+−−−−−−−−−−−−−+
Then after b = a
:
a−−−−+
| +−−−−−−−−−−−−−+
+−−−>| (Array) |
| +−−−−−−−−−−−−−+
b−−−−+ | Index 1: 1 |
| Index 2: 2 |
+−−−−−−−−−−−−−+
Then after c = copy(a)
:
a−−−−+
| +−−−−−−−−−−−−−+
+−−−>| (Array) |
| +−−−−−−−−−−−−−+
b−−−−+ | Index 1: 1 |
| Index 2: 2 |
+−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+
c−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+
| Index 1: 1 |
| Index 2: 2 |
+−−−−−−−−−−−−−+
Then after a[1] = 42
:
a−−−−+
| +−−−−−−−−−−−−−+
+−−−>| (Array) |
| +−−−−−−−−−−−−−+
b−−−−+ | Index 1: 42 |
| Index 2: 2 |
+−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+
c−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+
| Index 1: 1 |
| Index 2: 2 |
+−−−−−−−−−−−−−+
In contrast, the answer you refer to was dealing with an array of arrays:
# The `a`, `b`, an `c` from the other answer (without the [4,5,6] array)
+−−−−−−−−−−−−−−+
a−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−−+
| Index 1: |−−−−−+
| Index 2: ... | |
+−−−−−−−−−−−−−−+ |
|
| +−−−−−−−−−−−−−−+
+−−−−>| (Array) |
| +−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+ | | Index 1: 1 |
b−−−−−−−−>| (Array) | | | Index 2: 2 |
+−−−−−−−−−−−−−−+ | | Index 3: 3 |
| Index 1: |−−−−−+ +−−−−−−−−−−−−−−+
| Index 2: ... |
+−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
c−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−+
| Index 1: |−−−−−−−−−−>| (Array) |
| Index 2: ... | +−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+ | Index 1: 1 |
| Index 2: 2 |
| Index 3: 3 |
+−−−−−−−−−−−−−−+
So when they did a[1][1] = 111
, it changed the one a
and b
were (indirectly) pointing to, but not the one c
was pointing to:
# The `a`, `b`, an `c` from the other answer (without the [4,5,6] array)
+−−−−−−−−−−−−−−+
a−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−−+
| Index 1: |−−−−−+
| Index 2: ... | |
+−−−−−−−−−−−−−−+ |
|
| +−−−−−−−−−−−−−−+
+−−−−>| (Array) |
| +−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+ | | Index 1: 111 |
b−−−−−−−−>| (Array) | | | Index 2: 2 |
+−−−−−−−−−−−−−−+ | | Index 3: 3 |
| Index 1: |−−−−−+ +−−−−−−−−−−−−−−+
| Index 2: ... |
+−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
c−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−+
| Index 1: |−−−−−−−−−−>| (Array) |
| Index 2: ... | +−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+ | Index 1: 1 |
| Index 2: 2 |
| Index 3: 3 |
+−−−−−−−−−−−−−−+
array b = copy(array a)
differs fromarray b = array a
when adding new elements? – Hocuspocusa
,b
will stay unchanged. – Ira = ones(3); b = copy(a); a[3] = 111
. Why is there such a difference between the link and this example? – Lakeeshaa
,b
can be changed (in those cases where this is possible), but if you altera
itself by replacing an element,b
does not see this. – Ir