# Can I modify the fields of a designed structure?

**URL:** <https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 12, 2022, 9:42pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980 "2022-05-12T21:42:55Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [May 12, 2022, 9:42pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/1 "2022-05-12T21:42:55Z")

</div>

I was working on a structure with theirs fields are vectors and matrices and I have a vector of it. I need to change elements of this vector to be of a structure which its fields are static vectors and matrices. How can I do that?

---

<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:** [May 12, 2022, 9:50pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/2 "2022-05-12T21:50:44Z")

</div>

I’m not sure what is your doubt, but be careful in that:

```julia
julia> isconcretetype(MVector{Float64})
false

julia> isconcretetype(MVector{3,Float64})
true

julia> isconcretetype(MMatrix{Float64})
false

julia> isconcretetype(MMatrix{3,3,Float64,9})
true

```

(meaning that your `RRs` structure has abstract fields as it is)

Concerning the rest, I don’t think I get what you want, but maybe something like this:

```julia
julia> struct A
           x::Vector{Float64}
       end

julia> struct B
           x::SVector{3,Float64}
       end

julia> B(a::A) = B(SVector{3,Float64}(a.x...))
B

julia> a = A(rand(3))
A([0.8719748854921427, 0.48118038068468383, 0.9809479464441135])

julia> B(a)
B([0.8719748854921427, 0.48118038068468383, 0.9809479464441135])

julia> v = [A(rand(3)), A(rand(3))]
2-element Vector{A}:
 A([0.3015634495239551, 0.6358999576371009, 0.09630161737144594])
 A([0.5218204629518881, 0.289523727629152, 0.16346835337852283])

julia> B.(v)
2-element Vector{B}:
 B([0.3015634495239551, 0.6358999576371009, 0.09630161737144594])
 B([0.5218204629518881, 0.289523727629152, 0.16346835337852283])

```

---

<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:** [May 13, 2022, 3:27pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/5 "2022-05-13T15:27:13Z")

</div>

You don’t need the `MVector(....)` call at all when constructing `B`. You can write this as simply as:

```julia
B(a::A) = B(a.x, a.d)

```

You can also automatically generate a function like this with `@eval`:

```julia
@eval B(a::A) = B($([:(a.$x) for x in fieldnames(A)]...))

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 16, 2022, 8:49pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/8 "2022-05-16T20:49:59Z")

</div>

In which sense? What do you mean by identical?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 17, 2022, 4:29pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/10 "2022-05-17T16:29:25Z")

</div>

From where `VVector` comes? I am not aware of this data structure. About the differences:

1. You can only do something like `Bx[i].d = rand(3,3)*rand(3)`, i.e., replacing the whole array in a swoop, if the `struct` you define is mutable.
2. If your `struct` is not mutable, then you can yet change the values inside the matrix if the matrix type is mutable. `MVector` is mutable and, while you cannot replace the whole `MVector` with a new one, you can replace the values inside it with `Bx[i].d .= rand(3,3)*rand(3)` (notice the dot before the equal sign).
3. If your struct is not mutable neither the type of the matrix inside it then you cannot modify its value after creation and must create a new object to pass around each time you need the value to be changed.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 17, 2022, 9:26pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/13 "2022-05-17T21:26:03Z")

</div>

About (1), I mean that you cannot replace the array inside the struct by an entirely new array, the array used in the construction of the struct will always be the same, the only thing that can be changed is its contents.

```julia
julia> struct A; a :: Vector{Int}; end

julia> x = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> a_var = A(x)
A([1, 2, 3])

julia> a_var.a = [4, 5, 6]
ERROR: setfield! immutable struct of type A cannot be changed
Stacktrace:
 [1] setproperty!(::A, ::Symbol, ::Array{Int64,1}) at ./Base.jl:34
 [2] top-level scope at REPL[4]:1

julia> x
3-element Array{Int64,1}:
 1
 2
 3

julia> a_var.a .= [4, 5, 6]
3-element Array{Int64,1}:
 4
 5
 6

julia> x
3-element Array{Int64,1}:
 4
 5
 6

julia> mutable struct B; b :: Vector{Int}; end

julia> y = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> b_var = B(y)
B([1, 2, 3])

julia> b_var.b = [4, 5, 6]
3-element Array{Int64,1}:
 4
 5
 6

julia> y
3-element Array{Int64,1}:
 1
 2
 3

julia> b_var.b
3-element Array{Int64,1}:
 4
 5
 6

julia> b_var.b
3-element Array{Int64,1}:
 4
 5
 6

```

1. Yes, you can.

I fell like the answers to some of your questions could be obtained by just running your code through the REPL.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 18, 2022, 8:05pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/15 "2022-05-18T20:05:26Z")

</div>

1. Yes. You cannot replace values inside `d` because the `SArray` object is immutable. However, the `B3` object is mutable, and therefore a new object may be assigned to field `d`.
2. What do you mean by _unique usage_? I do not undertsand the question.
3. You cannot “solve” the error. It is a consequence of you using a `SArray` (i.e., an immutable object), you cannot mutate an `SArray`. The best you can do is to create a new array with the changed values and assign it. `a_var.d = [4, 5, a_var.d[3]]`

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 19, 2022, 8:59am UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/17 "2022-05-19T08:59:25Z")

</div>

`mutate` does not exist, not as a function, at least. Mutation happens when you use `=` but the left-hand side is not _just_ a variable name but a field inside an object (or a position inside an array). For example, `a = 10` is a _binding_ that binds the name `a` to the value 10 (i.e., **not mutation** ) but `a.my_field = 10` is an _assignment_ of the value 10 to the field `my_field` of object `a` (i.e., **a mutation** ). `a = 10` is a language primitive, `a.my_field = 10` calls `Base.setproperty!(a, :my_field, 10)` and its meaning can be changed by adding methods to this function. Finally, `.=` is another completely distinct thing, it can never be used for binding (i.e., to create a new variable) it only works on already existing objects/variables _that are containers_ and it _mutates_ each element of the container in the left-hand side to the value of the elements on the container of the right-hand side. You can use `?.=` in the REPL to check its documentation, it is replaced by Julia to a call to `broadcast!(identity, left_hand_variable, right_hand_variable)`.

In other words, things that look similar are completely different things, in fact.

---

<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:** [May 19, 2022, 9:06am UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/18 "2022-05-19T09:06:05Z")

</div>

See: [Assignment and mutation · JuliaNotes.jl](https://m3g.github.io/JuliaNotes.jl/stable/assignment/)

It compiles other previous answers to that.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [May 19, 2022, 8:03pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/19 "2022-05-19T20:03:16Z")

</div>

> [@Amro](#):
>
> `a_var = B3([1,2,3])`

Thank you very much for explanation. I know that in Julia a scalar is immutable. However, if I have an immutable structure `B3`, is there any way (a trick) to change its scalar property `s` to be mutable, i.e. `B3` remains immutable?

```julia
struct B3
  d::MVector{3,Float64}
  s::Int64
end
a_var = B3([1,2,3],0)
a_var.d[1:3] = [6,6,6]
a_var.s = Int(4)
ERROR: setfield!: immutable struct of type B3 cannot be changed

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 20, 2022, 12:23am UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/20 "2022-05-20T00:23:54Z")

</div>

Not really.

You can change field `s` to be of type `Base.RefValue{Int64}` but this needs the `struct` definition to be different and you will need to use `[]` every time you want to access the value, as in:

```julia
julia> struct B3
         s::Base.RefValue{Int64}
       end

julia> b3 = B3(Ref(1))
B3(Base.RefValue{Int64}(1))

julia> b3.s[]
1

julia> b3.s[] = 2
2

julia> b3
B3(Base.RefValue{Int64}(2))

```

What you will probably want is to rebuild the object with everything the same except the changed value.

```julia
julia> struct B3
         d::Vector{Float64}
         s::Int64
       end

julia> b3 = B3([1, 2, 3], 10)
B3([1.0, 2.0, 3.0], 10)

julia> b3 = B3(b3.d, 11)
B3([1.0, 2.0, 3.0], 11)

```

There is a library called [`Setfield.jl`](https://github.com/jw3126/Setfield.jl) that make it easier to re-create an object changing just a single field, but note this is not the same as changing the original.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [May 20, 2022, 1:53pm UTC](https://discourse.julialang.org/t/can-i-modify-the-fields-of-a-designed-structure/80980/21 "2022-05-20T13:53:23Z")

</div>

Thank you very much for your very help feedbacks!
