函数范围内的 eval(访问函数 args) [英] eval in function scope (accessing function args)

查看:32
本文介绍了函数范围内的 eval(访问函数 args)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定:

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 之前),它看起来很好:

If I just look at it as a string (prior to running parse and eval) it looks fine:

"NuGene(mutate_copy(gene.fqnn),mutate_copy(gene.dcqnn))"

但是,eval 似乎不知道已传递给 mutate_copy 函数的基因.

However, eval doesn't seem to know about gene that has been passed into the mutate_copy function.

如何访问已传递到变异副本的基因参数?

How do I access the gene argument that's been passed into the mutate copy?

我试过了:

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

但这扩展了字符串中的基因,这不是我想要的.

But that expands the gene in the string which is not what I want.

推荐答案

不要使用 eval!在几乎所有情况下,除非你真的知道你在做什么,否则你不应该使用 eval.在这种情况下, eval 根本不起作用,因为它在全局(或模块)范围内运行,并且无法访问函数本地的变量(如参数 gene).

Don't use eval! In almost all cases, unless you really know what you're doing, you shouldn't be using eval. And in this case, eval simply won't work because it operates in the global (or module) scope and doesn't have access to the variables local to the function (like the argument gene).

虽然您发布的代码对于最小的工作示例来说还不够,但我可以猜测您想在这里做什么.

While the code you posted isn't quite enough for a minimal working example, I can take a few guesses as to what you want to do here.

map(x->("mutate_copy(gene.$x)"),all_fields_except_score)可以动态查找字段名:

map(x->mutate_copy(gene.(x)), all_fields_except_score)

这是一种特殊的语法,最终可能会被 getfield(gene, x) 取代.不过,任何一个现在都可以工作.

This is a special syntax that may eventually be replaced by getfield(gene, x). Either one will work right now, though.

然后代替 eval(parse("$(T)("*join(all_fields_except_score,",")*")")),调用 T直接喷溅"字段值:

And then instead of eval(parse("$(T)("*join(all_fields_except_score,",")*")")), call T directly and "splat" the field values:

T(all_fields_except_score...)

我认为字段顺序在所有这些转换中应该是稳定的,但它看起来非常脆弱(您取决于分数是最后一个字段,并且所有构造函数的参数与其字段的顺序相同).看起来您正在尝试执行 deepcopy 类型的操作,但未初始化 score 字段.您也可以使用 Base 的 deepcopy 然后递归地将分数设置为零.

I think the field order should be stable through all those transforms, but it looks a pretty fragile (you're depending on the score being the last field, and all constructors to have their arguments in the same order as their fields). It looks like you're trying to perform a deepcopy sort of operation, but leaving the score field uninitialized. You could alternatively use Base's deepcopy and then recursively set the scores to zero.

这篇关于函数范围内的 eval(访问函数 args)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆