Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable fieldnames in Julia mutable structs

I would like to able to get fields from a mutable struct in Julia using a variable.

e.g.

mutable struct myType
    my_field1::Int = 1
    my_field2::Int = 2
    my_field3::Int = 3
end

And then let's imagine you declare a particular instance of this struct using struct_instance = myType()

How can you extract the value of a field from an instance of this mutable struct in a variable fashion?

Let's say you want to assign the value of my_struct.field[X] to a variable, using a for-loop, so that the particular field you're currently accessing depends on the variable X:

foo = zeros(Int64, 3)
for X = 1:3
    foo(X) = struct_instance.field[X]
end

I don't know how to actually implement the above for-loop -- what I wrote above is just pseudo-code above. In MATLAB you would use the following notation, for instance:

foo = zeros(1,3)
for x = 1:3
    foo(x) = struct_instance.(sprintf('field%d',x))
end

Thanks in advance.

like image 716
Conor Avatar asked Dec 22 '22 18:12

Conor


1 Answers

For the code at the beginning of your example to work you need the Paramaters package, otherwise you are not able to have default values (the code from your example throws an error). I use it very often exactly in situations where I need a struct to use to represent a bunch of variables.

using Parameters

@with_kw mutable struct MyType
    my_field1::Int = 1
    my_field2::Int = 2
    my_field3::Int = 3
end

This generates also a set of keyword methods that can be used to set the fields programmatically when creating the object. Have a look at the following code:

julia> vals = [Symbol("my_field$i") =>10i for i in 2:3 ]
2-element Array{Pair{Symbol,Int64},1}:
 :my_field2 => 20
 :my_field3 => 30

julia> MyType(;vals...)
MyType
  my_field1: Int64 1
  my_field2: Int64 20
  my_field3: Int64 30

We have created here a set of field names and now we are using it when creating an object. This approach is particularly useful when you could consider using immutable object instead of mutable ones (immutable objects are always much faster).

You can mutate the object using setfield!:

julia> for i in 1:2
           setfield!(m,Symbol("my_field$i"), 20i)
       end
julia> m
MyType
  my_field1: Int64 20
  my_field2: Int64 40
  my_field3: Int64 30

I think that when you are coming from Matlab this would be the most convenient way to layout your structs.

like image 72
Przemyslaw Szufel Avatar answered Dec 31 '22 05:12

Przemyslaw Szufel