Reputation: 1145
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
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
Reputation: 10984
You can access fields with Symbol
s, 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