Econ
Econ

Reputation: 1145

Access struct fields within a function by string argument

Say I have a struct,

struct MyStruct

a
b

end

Is there some way to write a function like the following

function doSomething(x::MyStruct,fieldName::String)

y = x.fieldName

return f(y)

end

I could not find anything about this in the documentation / forums.

Upvotes: 0

Views: 1150

Answers (2)

Przemyslaw Szufel
Przemyslaw Szufel

Reputation: 42214

If you plan to get the value only few times redrikekre's solution is OK. However, using metaprogramming you can write code without efficiency penalty, see the getDoSomething2() function below.

Consider those three functions:

function doSomethingNative(x)
  return x.a
end

function doSomething(x, name::String)
    return getproperty(x, Symbol(name))
end

function getDoSomething2(name::String)
     field = Symbol(name)
     code = quote
         (obj) -> obj.$field
     end
     return eval(code)
end

Now the setup:

using BenchmarkTools
struct MyStruct
          a
          b
end
x = MyStruct(5,6)

Now the benchmarks:

julia> @btime doSomethingNative($x)
  0.001 ns (0 allocations: 0 bytes)
5

julia> @btime doSomething($x,"a")
  36.266 ns (0 allocations: 0 bytes)
5

julia> const doSomething2 = getDoSomething2("a");

julia> @btime doSomething2($x)
  0.001 ns (0 allocations: 0 bytes)
5

If you run @code_native doSomethingNative(x) and @code_native doSomething2(x) you will see that the assembly output is identical.

Upvotes: 1

fredrikekre
fredrikekre

Reputation: 10984

You can access fields with Symbols, so you can convert the string to a symbol and then use getproperty:

julia> struct MyStruct
           a
           b
       end

julia> function doSomething(x::MyStruct, name::String)
           s = Symbol(name)
           return getproperty(x, s)
       end
doSomething (generic function with 1 method)

julia> doSomething(MyStruct(1, 2), "a")
1

Note, however, that this will probably be very inefficient, since the compiler most likely can't see through this and thus your code might be type-unstable, see https://docs.julialang.org/en/v1/manual/performance-tips/.

Upvotes: 3

Related Questions