# Saving data into array having struct data type

**URL:** https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567
**Category:** General Usage
**Tags:** question
**Created:** [August 8, 2020, 12:31pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567 "2020-08-08T12:31:38Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![musman](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@musman](https://discourse.julialang.org/u/musman)
#### Post date: [August 8, 2020, 12:31pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567/1 "2020-08-08T12:31:38Z")

</div>

Hi, newbie to Julia.

I am trying to run the following

```julia
> struct Bus
> bus_num::Int64
> bus_type::Int64
> bus_area::Int64
> bus_vmag::Float64
> bus_vangle::Float64
> bus_vnom::Float64
> bus_vmax::Float64
> bus_vmin::Float64
> end
> 
> aBuses = Array{Bus}(undef,10)
> fields = ["Bus_N","Bus_Type","Area","V_Mag (pu)","V_Ang (deg)","V_Nom (kV)","Zone","V_max (pu)","V_min (pu)"];
> header = "Area";
> buses = aBuses[5,1]
> Dbus = 0
> # for i in 1:size(fields,1)
> idx = findall(x->x=="Area",fields)
> buses.bus_area = idx[1,1]
> # Dbus[:,i] = data[:,idx]
> # end

```

However, when I reach the last line

```julia
buses.bus_area = idx[1,1]

```

I received an error that

LoadError: setfield! immutable struct of type Bus cannot be changed

While reading the Julia manual, I understood that once an immutable struct has been defined, it is not possible to change its fields but it is still possible to change the value of a field. Apparently, it seems that this is not the case or I have not understood it right.  
Since i am working on the modelling of an electrical network, my idea is to save the data of each bus, line, etc in a struct container (defined for each bus, line etc) and then store all these containers in one array i.e., Array\_Bus = [bus\_1\_container, bus\_2\_container, and so on], where bus\_1\_container is the struct Bus that I have already defined in the code. However, I am unable to save the data for each individual field of the struct Bus due to the error that I have mentioned.

If I declare the struct Bus as mutuable, then entries of

```julia
aBuses = Array{Bus}(undef,10)

```

aBuses become undefined and I no longer can access them while executing the command

```julia
buses = aBuses[5,1]

```

Can someone shed some light what is the problem and how can I solve it?

---

<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: [August 8, 2020, 1:00pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567/2 "2020-08-08T13:00:56Z")

</div>

> [@musman](#):
>
> While reading the Julia manual, I understood that once an immutable struct has been defined, it is not possible to change its fields but it is still possible to change the value of a field. Apparently, it seems that this is not the case or I have not understood it right.

You did not understand right. You cannot change the value of a field in an instance of an immutable `struct`. You can change the value of fields of an instance of a mutable struct stored inside a immutable object.

```julia
julia> mutable struct Mutable; a :: Int; b :: Float64; end

julia> struct Immutable; my_int :: Int; my_mutable_struct :: Mutable; end

julia> i = Immutable(10, Mutable(20, 30.0))
Immutable(10, Mutable(20, 30.0))

julia> i.my_int = 100
ERROR: setfield! immutable struct of type Immutable cannot be changed
...

julia> i.my_mutable_struct = Mutable(200, 300.0)
ERROR: setfield! immutable struct of type Immutable cannot be changed
...

julia> i.my_mutable_struct.a = 200
200

julia> i
Immutable(10, Mutable(200, 30.0))

```

For mutable or immutable structs it is impossible to change the existing fields after defining the type. If you want this you need to use a `Dict` or something like that. For your case (where you just wanna change values) I think a `mutable struct` will suffice.

---

<div class="post-metadata">

### Author: ![musman](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@musman](https://discourse.julialang.org/u/musman)
#### Post date: [August 8, 2020, 1:42pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567/3 "2020-08-08T13:42:26Z")

</div>

Thanks for the clarification. As I said in my original post that when I used the mutable Struct type and initialize the

```julia
aBuses = Array{Bus}(undef,10)

```

then, I got this output

```julia

Vector{Bus} with 10 elements
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef

```

and now, I can no longer access the field of abuses through

```julia
aBuses.bus_num = 10

```

So, with immutable struct, I cannot modify the values of a field and if i declare a mutable struct, and then initialize an array, there are no longer any entries of type mutable struct in the resulting array. Is there any specific reason, why there are no entries of type mutable struct when I initialize an Array?

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [August 8, 2020, 3:11pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567/4 "2020-08-08T15:11:55Z")

</div>

`aBuses` is an empty array of buses. `#undef` is telling you there’s nothing in that entry. You should be able to do:

```julia
aBuses[1] = Bus(1,2,3,4,5,6,7,8)

```

And then, since `Bus` is mutable, you could mutate it later:

```julia
aBuses[1].bus_num = 10

```

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [August 8, 2020, 3:24pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567/5 "2020-08-08T15:24:24Z")

</div>

I think one source of confusion is that there seems to be a difference in behaviour of `undef` during array construction for a `struct` compared to a `mutable struct`. Consider:

```julia
julia> struct Bus 
           bus_num::Int 
       end

julia> aBuses = Array{Bus}(undef, 2)
2-element Array{Bus,1}:
 Bus(140449318305968)
 Bus(140449315843744)

julia> mutable struct 
           Bus2 bus_num::Int 
       end

julia> aBuses2 = Array{Bus2}(undef, 2)
2-element Array{Bus2,1}:
 #undef
 #undef

```

so in both cases you get an `Array{Bus, 1}` back, however with a `struct` there are `Bus` objects in the array (with whatever happened to be at that memory location previously reinterpreted as an `Int`), while with the `mutable struct` you get `#undef` fields.

As @tomerarnon points out that just means that you need to populate your array with `Bus` objects after creation if you want to manipulate the fields of those objects.

---

<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: [August 8, 2020, 4:02pm UTC](https://discourse.julialang.org/t/saving-data-into-array-having-struct-data-type/44567/6 "2020-08-08T16:02:14Z")

</div>

To complement what @tomerarnon said.

1. `aBuses` s not an empty array of buses (`isempty` will return `false`), but a vector of length `10` of buses, they just happen to be non-initialized (i.e., they are like a `NULL` pointer to that object in `C/C++`). They count as value of that type (you can see the vector only allow `Bus` objects) but you cannot do anything with them (they do not really exist), you need to replace them with initialized objects.
2. You can either:
  1. Create the `Vector` with the correct length but with uninitialized buses (like you are are doing) and then after loop through the vector assigning initialized bus objects to the positions.
  2. Create an empty `Vector` and then call `push!` repeatedly, filling it with newly create bus objects at each call.
  3. Create the vector with the right length and initialized objects by using a list comprehension `aBuses = [Bus(i, common_type, other_info[i]...) for i in 1:10 ]`.
  4. DO NOT: `fill(bus_object, 10)` this will create a vector of length 10 in which EVERY ELEMENT REFER TO THE SAME OBJECT. Is often a rookie mistake, but even people more experienced with Julia (like me) will forget that one time or another and end up with curious bugs.
