# Assign a struct variable to a new variable

**URL:** <https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723>\
**Category:** General Usage\
**Tags:** struct\
**Created:** [July 24, 2022, 7:38pm UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723 "2022-07-24T19:38:17Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![yang\_chen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yang_chen/32/38210_2.png) [@yang\_chen](https://discourse.julialang.org/u/yang_chen)\
**Post date:** [July 24, 2022, 7:38pm UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/1 "2022-07-24T19:38:17Z")

</div>

Hi, I defined a struct. Then I create a new variable like  
A = Pos(“id1”, 1, 2, 1, 2)  
Then I assign the A to another variable B.  
B = A;  
Next, I tried to modify B,  
B.posX1 = 3  
B.posY1 = 4

However, when I check A, I find A is also modified to B.  
A and B are same after I modified B. It’s weird and dangerous. I think julia should create a new memory for B. But A and B are using same memory space.

What should I do if I want to create a new memory space for B? Thanks.

Pos(“id1”, 3, 4, 1, 2) # A  
Pos(“id1”, 3, 4, 1, 2) #B

mutable struct Pos  
id  
posX1::Int32  
posY1::Int32  
posX2::Int32  
posY2::Int32  
end

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 24, 2022, 8:37pm UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/2 "2022-07-24T20:37:29Z")

</div>

This is _always_ how `=` works in Julia, in every case. If you do `a = b`, then `a` and `b` are the _same_ value, and modifying one will modify the other.

If you want to _copy_ `b`, then you need to be explicit about that. First, you need to define a way to copy your struct:

```julia
function Base.copy(p::Pos)
  Pos(p.id, p.posX1, ...)
end

```

and then call it:

```julia
a = copy(b)

```

---

<div class="post-metadata">

**Author:** ![yang\_chen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yang_chen/32/38210_2.png) [@yang\_chen](https://discourse.julialang.org/u/yang_chen)\
**Post date:** [July 24, 2022, 8:39pm UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/3 "2022-07-24T20:39:16Z")

</div>

Thanks rdeits. It’s reasonble. I will do create a new variable for it.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 24, 2022, 10:47pm UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/4 "2022-07-24T22:47:53Z")

</div>

> [@rdeits](#):
>
> This is _always_ how `=` works in Julia, in every case. If you do `a = b`, then `a` and `b` are the _same_ value, and modifying one will modify the other

Sorry for the basic question treated here many times, but why are scalars different?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [July 24, 2022, 11:12pm UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/5 "2022-07-24T23:12:40Z")

</div>

> [@rafael.guerra](#):
>
> scalars different?

scalar are just special case of `immutable`, any immutable behaves like “scalars”

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 25, 2022, 12:34am UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/6 "2022-07-25T00:34:33Z")

</div>

> [@yang\_chen](#):
>
> It’s weird and dangerous.

It is in some sense, yes, and it is even more confusing when we notice that immutable variables behave “differently” (like scalars).

But note that this is the exact same behavior in Python:

```python
In [5]: a = [1, 2, 3]                                                                                                                  

In [6]: b = a                                                                                                                          

In [7]: b[0] = 0                                                                                                                       

In [8]: a                                                                                                                              
Out[8]: [0, 2, 3]

In [9]: a = 1                                                                                                                          

In [10]: b = a                                                                                                                         

In [11]: b = 2                                                                                                                         

In [12]: a                                                                                                                             
Out[12]: 1

```

Thus, it is something that one has to understand and get used to, not only in Julia. The difference between mutable and immutable objects and when one or other are useful, is important in code design. And soon enough you will face the additional complication on [mutability vs. assignment](https://m3g.github.io/JuliaNotes.jl/stable/assignment/), which appears as frequently as a new user question.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 25, 2022, 1:00am UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/7 "2022-07-25T01:00:12Z")

</div>

> [@rafael.guerra](#):
>
> Sorry for the basic question treated here many times, but why are scalars different?

They’re not different, at least not in terms of the observable behavior of the program.

If you do `a = b`, then `a` and `b` are the same value. Any mutations of `b` affect `a` as well. It just happens that for immutable objects (i.e. numbers), you _can’t_ mutate `b` (or `a`), so the question of whether mutating one affects the other never arises.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 25, 2022, 1:17am UTC](https://discourse.julialang.org/t/assign-a-struct-variable-to-a-new-variable/84723/8 "2022-07-25T01:17:10Z")

</div>

Maybe it’s just the classic confusion between reassignment of a variable and mutation of an instance; this is common for people coming from languages where “a variable” is basically a named instance. Although the separation of variable and instance along with mutability/immutability is a safer and simpler abstraction than pointer logic, it’s not entirely straightforward, to be fair.

It helped me to first imagine an immutable instance to have a primary sequence of bytes, and that’s exactly how they are identified; if two immutable instances have the same sequence, they _are_ the same, even if you constructed them separately. A mutable instance however is an address to a remote data, and it’s identified by that address; separate copies of equal data at separate addresses are different instances. This works out for immutable structs with mutable fields, because its primary sequence only contains the address of the mutable field instance, not its remote data. When you mutate an instance, you change the remote data, not its address, so the identity remains the same.

A variable is just a named reference to an instance so that your code has access; 1 instance can have many references. _Assignments_ are how you make a reference to an instance. You use a variable to access an instance in order to mutate it, e.g. `am.num = 1`, `arr[2] = 5`, `push!(arr, 3)`, but that is _not_ the same as reassigning that variable to a possibly different instance e.g. `am = MutInt(1)`. It might look similar sometimes, and indeed in `am.num = 1` you are reassigning the field `.num` of the instance to mutate it, but the variable `am` itself is just used for access, not being reassigned.

By this point, it should be clear that `B = A` in the OP accesses the variable `A` to get an instance, then assigns the same instance to variable `B`. That instance has 2 variables `A` and `B`, and there was only 1 instance to mutate, no matter which variable is used to access it. To assign a separate instance to `B`, you need to create a separate instance, e.g. `B = copy(A)` or `B = A + 0`.

> **Open to see behavior of variables with immutable instances. Note that no instance is ever mutated.**
>
> ```julia
> julia> a = 3
> 3
> 
> julia> b = a # access variable a, get instance 3, assign 3 to variable b
> 3
> 
> julia> a === b # same instance has 2 variables
> true
> 
> julia> a += 1 # compute a+1, then reassign result to a
> 4
> 
> julia> a === b # different instance because immutable value differs
> false
> 
> julia> b = 4 # make instance 4, assign 4 to variable b
> 4
> 
> julia> a === b # same instance because immutable value is same
> true
> 
> ```

> **Open to see behavior of variables with mutable instances. Note that the reassignment behavior is the same as immutable ones, the difference is mutability and identity rules.**
>
> ```julia
> julia> mutable struct MutInt num::Int end
> 
> julia> Base.:+(x::MutInt, y::Int) = MutInt(x.num+y)
> 
> julia> am = MutInt(3)
> MutInt(3)
> 
> julia> bm = am # access variable am, get instance, assign it to variable bm
> MutInt(3)
> 
> julia> am === bm # same instance has 2 variables
> true
> 
> julia> am.num = 1 # access variable am, mutate its instance by reassigning its field num
> 1
> 
> julia> am === bm # 2 variables still access the same instance
> true
> 
> julia> am += 1 # compute am+1, then reassign result to am
> MutInt(2)
> 
> julia> am === bm # different instance because mutable addresses differ
> false
> 
> julia> bm.num = am.num # mutate so fields are equal
> 2
> 
> julia> am === bm # different instance because mutable addresses differ
> false
> 
> ```
