Julia 通过字符串参数访问函数中的结构字段

Julia 通过字符串参数访问函数中的结构字段,julia,Julia,假设我有一个结构 struct MyStruct a b end 有没有办法编写如下函数 function doSomething(x::MyStruct,fieldName::String) y = x.fieldName return f(y) end 我在文档/论坛中找不到关于此的任何信息。您可以使用符号访问字段,因此您可以将字符串转换为符号,然后使用getproperty: julia> struct MyStruct a

假设我有一个结构

struct MyStruct

a
b

end
有没有办法编写如下函数

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

y = x.fieldName

return f(y)

end

我在文档/论坛中找不到关于此的任何信息。

您可以使用
符号访问字段,因此您可以将字符串转换为符号,然后使用
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

但是请注意,这可能会非常低效,因为编译器很可能无法看穿这一点,因此您的代码可能是类型不稳定的,请参见。

您可以使用
Symbol
s访问字段,因此您可以将字符串转换为符号,然后使用
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

但是,请注意,这可能会非常低效,因为编译器很可能无法看穿这一点,因此您的代码可能是类型不稳定的,请参阅。

如果您计划只获得几次该值,redrikekre的解决方案是可以的。但是,使用元编程,您可以编写代码,而不会降低效率,请参阅下面的
getDoSomething2()
函数

考虑这三项职能:

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
现在开始设置:

using BenchmarkTools
struct MyStruct
          a
          b
end
x = MyStruct(5,6)
现在,基准:

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

如果运行
@code\u native doSomethingNative(x)
@code\u native doSomething2(x)
,您将看到程序集输出是相同的。

如果您计划只获得几次该值,redrikekre的解决方案是可以的。但是,使用元编程,您可以编写代码,而不会降低效率,请参阅下面的
getDoSomething2()
函数

考虑这三项职能:

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
现在开始设置:

using BenchmarkTools
struct MyStruct
          a
          b
end
x = MyStruct(5,6)
现在,基准:

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
如果运行
@code\u native doSomethingNative(x)
@code\u native doSomething2(x)
,您将看到程序集输出是相同的