# Modify elements of struct without changing original inputs

**URL:** <https://discourse.julialang.org/t/modify-elements-of-struct-without-changing-original-inputs/37592>\
**Category:** General Usage\
**Created:** [April 14, 2020, 10:06pm UTC](https://discourse.julialang.org/t/modify-elements-of-struct-without-changing-original-inputs/37592 "2020-04-14T22:06:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![corbat](https://avatars.discourse-cdn.com/v4/letter/c/e0b2c6/32.png) [@corbat](https://discourse.julialang.org/u/corbat)\
**Post date:** [April 14, 2020, 10:06pm UTC](https://discourse.julialang.org/t/modify-elements-of-struct-without-changing-original-inputs/37592/1 "2020-04-14T22:06:32Z")

</div>

Hi,

I have a question regarding a situation where I want to pass a (mutable) struct to another struct.  
Please see the MWE below.

```julia
mutable struct MyStruct
    arr::Array{Real, 1}
end

struct MyOtherStruct
    ms::MyStruct
end

function square_MyOtherStruct(mos::MyOtherStruct)
    mos.ms.arr = mos.ms.arr.^2
end

my_struct = MyStruct([1, 2, 3])
my_other_struct = MyOtherStruct(my_struct)

square_MyOtherStruct(my_other_struct)

```

This results in:

```julia
println(my_other_struct.ms.arr)
 [1,4,9]
println(my_struct.arr)
 [1,4,9]

```

What I would like to achieve is to modify the `ms::MyStruct` element within the `MyOtherStruct` without changing the `mystruct` variable that is passed to create the `MyOtherStruct`.

So I would like to (still) have:

```julia
println(my_other_struct.ms.arr)
 [1,4,9]
println(my_struct.arr)
 [1,2,3]

```

In my actual application, I want the user to still have “original” `my_struct` object at hand to proceed using this, while also able to perform other operations on the `MyOtherStruct` object that might include modifications of the contained values.

I know that this is possible by using a constructor for `MyOtherStruct` that makes a `deepcopy` of the `MyStruct` object before construction.

But I was wondering whether this is a recommended way of doing this or if there is a cleaner solution, especially since I read that using `deepcopy` is usually not a good thing and might also have some negative effects on the performance.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 14, 2020, 10:15pm UTC](https://discourse.julialang.org/t/modify-elements-of-struct-without-changing-original-inputs/37592/2 "2020-04-14T22:15:08Z")

</div>

> [@corbat](#):
>
> What I would like to achieve is to modify the `ms::MyStruct` element within the `MyOtherStruct` without changing the `mystruct` variable that is passed to create the `MyOtherStruct` .

Either make a copy or use a non-mutable `struct`. Having changes visible to other references is the whole point of a `mutable struct`.

Even if you use a non-mutable `struct`, if it has a mutable member like an `Array` then you have to make a copy of that if you don’t want changes visible to other places that refer to the same `Array`. For example, if you did

```julia
mos.ms.arr .= mos.ms.arr.^2

```

(note the `.=`) which mutates `mos.ms.arr` in place rather than making a new array and re-assigning `mos.ms.arr` (as in your `square_MyOtherStruct` code above), then even if `ms` is non-mutable the change to `arr` will be visible to other places that refer to `arr`.

(Note also that your abstract element type in `arr::Array{Real, 1}` will kill performance. It’s better to use a parameterized `struct` type so that you can use a concretely-typed `Array` here.)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 15, 2020, 6:53am UTC](https://discourse.julialang.org/t/modify-elements-of-struct-without-changing-original-inputs/37592/3 "2020-04-15T06:53:14Z")

</div>

> [@corbat](#):
>
> if there is a cleaner solution

There are some packages which provide a convenient API to make a copy with one field modified, eg

> **[GitHub - jw3126/Setfield.jl: Update deeply nested immutable structs.](https://github.com/jw3126/Setfield.jl)**
>
> Update deeply nested immutable structs. Contribute to jw3126/Setfield.jl development by creating an account on GitHub.
