# Views of arrays inside a mutable struct

**URL:** <https://discourse.julialang.org/t/views-of-arrays-inside-a-mutable-struct/88337>\
**Category:** General Usage\
**Created:** [October 6, 2022, 10:46am UTC](https://discourse.julialang.org/t/views-of-arrays-inside-a-mutable-struct/88337 "2022-10-06T10:46:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![SiddhantDeshmukh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/siddhantdeshmukh/32/35324_2.png) [@SiddhantDeshmukh](https://discourse.julialang.org/u/SiddhantDeshmukh)\
**Post date:** [October 6, 2022, 10:46am UTC](https://discourse.julialang.org/t/views-of-arrays-inside-a-mutable-struct/88337/1 "2022-10-06T10:46:42Z")

</div>

Hi, I’m encountering some unexpected behaviour when using views of arrays inside of a mutable struct. Here is the basic structure:

```julia
using Parameters
@with_kw mutable struct Grid
  prim::Array{Float64, 3} = zeros(Float64, 14, 1, 2)
  rho::Matrix{Float64} = @view prim[:, :, 1]
  p::Matrix{Float64} = @view prim[:, :, 2]
end

```

In a separate function, I do

```julia
function init_sod!(g::Grid)
  @. g.rho[3:7, :] = 1.0
  @. g.rho[8:12, :] = 0.125
  @. g.p[3:7, :] = 1.0
  @. g.p[8:12, :] = 0.1
  return g
end

```

After calling

```julia
g = Grid()
g = init_sod!(g)

```

I find that the array ‘prim’ is still initialised to zero. I also tested this in the REPL by creating Grid() and assigning values to ‘rho’ and ‘p’ outside of the function (i.e. not assigning the returned Grid from the function call) and got the same behaviour. ‘g.rho’ and ‘g.p’ are correctly set, but ‘g.prim’ does not have the values. I don’t understand this, since assigning these views when these members are outside of the mutable struct (global scope) works as expected:

```julia
prim = zeros(Float64, 14, 1, 2)
rho = @view prim[:, :, 1]
p = @view prim[:, :, 2]

@. rho[3:7] = 1.0
@. rho[8:12] = 0.125
@. p[3:7] = 1.0
@. p[8:12] = 0.1

```

Both ‘prim’ and the arrays (‘rho’, ‘p’) have the new values. How can I replicate this behaviour with the original setup, i.e. when the arrays are inside a mutable struct?

---

<div class="post-metadata">

**Author:** ![maltezfaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maltezfaria/32/7728_2.png) [@maltezfaria](https://discourse.julialang.org/u/maltezfaria)\
**Post date:** [October 6, 2022, 11:10am UTC](https://discourse.julialang.org/t/views-of-arrays-inside-a-mutable-struct/88337/2 "2022-10-06T11:10:12Z")

</div>

I think the issue is that the fields `rho` and `p` of your `Grid` structure are of type `Matrix`, so the views get [converted](https://docs.julialang.org/en/v1/manual/conversion-and-promotion/) to that type upon construction. This means a **new copy** is made, and therefore mutating it will not change `prim`. It works on the `REPL` because there you do not enforce a type on `rho` and `p`, and so they are truly views. If you really want to have `rho` and `p` as views of `prim` on `Grid`, they should be of `SubArray` type (with possibly a bunch of parametric arguments).

But alternatively, you may want to have only `prim` as a field in `Grid`, and have _getters_, like  
`rho(g::Grid) = view(g.grid,:,:,1)` that will behave as you want…

---

<div class="post-metadata">

**Author:** ![RayleighLord](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayleighlord/32/33592_2.png) [@RayleighLord](https://discourse.julialang.org/u/RayleighLord)\
**Post date:** [October 6, 2022, 11:11am UTC](https://discourse.julialang.org/t/views-of-arrays-inside-a-mutable-struct/88337/3 "2022-10-06T11:11:13Z")

</div>

If you define

```julia
using Parameters
@with_kw mutable struct Grid
  prim::Array{Float64, 3} = zeros(Float64, 14, 1, 2)
  rho = @view prim[:, :, 1]
  p = @view prim[:, :, 2]
end

```

then you get your desired behaviour. The problem is when you declare the type of `rho` and `p` as a `Matrix`, the view gets promoted to match that type so a copy of prim is made.

---

<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:** [October 6, 2022, 2:01pm UTC](https://discourse.julialang.org/t/views-of-arrays-inside-a-mutable-struct/88337/4 "2022-10-06T14:01:36Z")

</div>

You could also use:

> [@SiddhantDeshmukh](#):
>
> ```julia
> using Parameters
> @with_kw mutable struct Grid{A,B,C}
> prim::A = zeros(Float64, 14, 1, 2)
> rho::B = @view prim[:, :, 1]
> p::C = @view prim[:, :, 2]
> end
> 
> ```
