【发布时间】:2020-07-31 19:43:29
【问题描述】:
假设我有一些不可变的结构,例如
struct Person
name::Symbol
age::Int
end;
我想写一个函数
function copyWithModification(original_person::Person, fieldToChange::String, valueForNewField)::Person
它返回一个新的 Person 结构,就像旧的一样,除了 fieldToChange 中指定的字段的值已设置为 valueForNewField。我该怎么做?
我目前的尝试使用Setfield 和元编程
using Setfield
function copyWithModification(original_person::Person, fieldToChange::String, valueForNewField)::Person
return eval(Meta.parse("@set original_person." * fieldToChange * " = " * string(valueForNewField)))
end
这不起作用,因为 eval 是在全局范围内执行的,因此无法访问 original_person 对象:
julia> struct Person
name::Symbol
age::Int
end;
julia> using Setfield
julia> function copyWithModification(original_person::Person, fieldToChange::String, valueForNewField)::Person
return eval(Meta.parse("@set original_person." * fieldToChange * " = " * string(valueForNewField)))
end
copyWithModification (generic function with 1 method)
julia> person_local_scope = Person(:test, 10)
Person(:test, 10)
julia> copyWithModification(person_local_scope, "age", 20)
ERROR: UndefVarError: original_person not defined
Stacktrace:
[1] top-level scope at /Users/lionstarr/.julia/packages/Setfield/XM37G/src/sugar.jl:182
[2] eval at ./boot.jl:330 [inlined]
[3] eval(::Expr) at ./client.jl:425
[4] copyWithModification(::Person, ::String, ::Int64) at ./REPL[3]:2
[5] top-level scope at REPL[5]:1
julia>
我应该注意我不关心这段代码的性能;它只会被调用一次或两次。关键是要节省代码复制和人为错误,因为我实际要使用此代码的结构要大得多。
【问题讨论】:
标签: struct julia metaprogramming