假设:
abstract ABSGene
type NuGene <: Genetic.ABSGene
fqnn::ANN
dcqnn::ANN
score::Float32
end
function mutate_copy{T<:ABSGene}(gene::T)
all_fields_except_score = filter(x->x != :score, names(T))
all_fields_except_score = map(x->("mutate_copy(gene.$x)"),all_fields_except_score)
eval(parse("$(T)("*join(all_fields_except_score,",")*")"))
end
ng = NuGene()
mutated_ng = mutate_copy(ng)
结果:
ERROR: gene not defined
in mutate_copy at none:4
如果我只是将它看作一个字符串(在运行parse和eval之前),它看起来很好:
"NuGene(mutate_copy(gene.fqnn),mutate_copy(gene.dcqnn))"
然而,eval似乎并不知道已经传递给mutate_copy函数的基因。
如何访问已传递给mutate副本的基因参数?
我试过了:
function mutate_copy{T<:ABSGene}(gene::T)
all_fields_except_score = filter(x->x != :score, names(T))
all_fields_except_score = map(x-> ("mutate_copy($gene.$x)"),all_fields_except_score)
eval(parse("$(T)("*join(all_fields_except_score,",")*")"))
end
但是这扩展了字符串中的基因,这不是我想要的。
答案 0 :(得分:2)
不要使用eval
!几乎在所有情况下,除非您确实知道您正在做什么,否则您不应该使用eval
。在这种情况下,eval
根本无法工作,因为它在全局(或模块)范围内运行,并且无法访问函数本地的变量(如参数{{1 }})。
虽然你发布的代码对于一个最小的工作示例来说还不够,但我可以猜测你想在这里做些什么。
您可以动态查找字段名称,而不是gene
:
map(x->("mutate_copy(gene.$x)"),all_fields_except_score)
这是一种特殊语法,最终可能被map(x->mutate_copy(gene.(x)), all_fields_except_score)
取代。但是,现在任何一个都可以正常工作。
然后代替getfield(gene, x)
,直接致电eval(parse("$(T)("*join(all_fields_except_score,",")*")"))
,&#34; splat&#34;字段值:
T
我认为通过所有这些变换,字段顺序应该是稳定的,但它看起来非常脆弱(你依赖于得分是最后一个字段,所有构造函数的参数顺序与它们的顺序相同字段)。看起来您正在尝试执行T(all_fields_except_score...)
类型的操作,但是将得分字段保持未初始化状态。您也可以使用Base deepcopy
然后递归设置为零。