How to pass struct fields as function arguments?

Example

struct variables
   a :: Integer
   b :: Float64
   c :: Integer
end

function f(a::Integer,b::Float64,c::Integer)
   d = a + b + c
   println(d)
end

var = variables(1,2.5,3)

f(var)  # ?

How can I pass a structure as an input argument?

1 Like

EDIT 2: Here is how you actually should do this:

function f(var::variables)
  d = var.a + var.b + var.c
  println(d)
end

f(var)

You could also do this, although you shouldn’t, and it can’t be properly inferred by the compiler so it will involve dynamic dispatch:

f(getfield.(Ref(var), fieldnames(variables))...)

EDIT: Brief description:

Gets a Tuple of Symbols which refer to the field names of the variables struct type via fieldnames(variables), then uses a broadcasted getfield to get the values of those fields out of the var struct, and then splats them into the call to f.

You could instead do this as an @generated function if you want it to be inferrable.

2 Likes

FWIW, this seems like an unusual thing to do. For example, it changes behaviour when reordering the fields in the struct which isn’t very nice.

2 Likes

Agreed, the best thing to do is to just dispatch on the input as f(var::variables) = .... I think I misread the intent of the OP :laughing:

This is a very good case for Parameters.jl if you have a lot of variables:

using Parameters

@with_kw struct variables
   a :: Integer
   b :: Float64
   c :: Integer
end

function f(s::variables)
    @unpack_variables s
    d = a + b + c
    println(d)
end

julia> f(variables(1,2.5,3))
6.5
5 Likes