我知道你可以使用他们的名字来调用函数,如下所示
f = x -> println(x)
y = :f
eval(:($y("hi")))
但这很慢,因为它正在使用eval
是否可以以不同的方式执行此操作?我知道只需做symbol(f)
即可轻松走向另一个方向。
答案 0 :(得分:3)
你想要完成什么?需要评估符号听起来像是寻找问题的解决方案。特别是,您可以传递原始函数,从而避免需要跟踪f
范围的问题(或者,因为f
只是您示例中的普通变量,它可能会获得重新分配,并输入更少的字符:
f = x -> println(x)
g = f
g("hi")
我知道只需
symbol(f)
即可轻松走向另一个方向。
这是误导性的,因为它实际上并不会让你回归f
(该变换将是非唯一的)。但它改为为您提供函数的字符串表示形式(有时可能恰好为f
)。它只相当于调用Symbol(string(f))
,因为这种组合很常见,可用于其他目的。
答案 1 :(得分:2)
实际上我已经找到了上述场景的用途。我正在研究一种简单的表格编译器,它可以方便地定义变量问题。有限元分析。
我依靠Julia解析器对语法进行初步分析。输入的公式是有效的Julia语法,但会在执行时触发错误,因为某些符号或方法在问题定义时不可用。
所以我所做的大概是这样的:
我有一个可以保存我的问题描述的类型:
type Cmd f; a; b; end
我已经定义了一个宏,以便我可以访问问题描述AST。我遍历此表达式并从其元素创建Cmd
对象(这与@mat
中MATLAB.jl
宏背后的策略完全不同):
macro m(xp)
c = Cmd(xp.args[1], xp.args[3], xp.args[2])
:($c)
end
稍后,我运行Cmd
。符号的评估只发生在这个阶段(是的,我需要注意评估环境):
function run(c::Cmd)
xp = Expr(:call, c.f, c.a, c.b)
eval(xp)
end
用法示例:
c = @m a^b
...
a, b = 2, 3
run(c)
返回9
。简而言之,这个问题至少与一些元编程方案有关。在我的情况下,我不得不承认我对表现并不在乎,因为所有这些仅仅是预处理和语法糖。