【发布时间】:2016-02-17 10:48:42
【问题描述】:
我想使用依赖于运行时的参数调用 Julia 包(JuMP 中的@defNLExpr)中的宏。参数是一个依赖于运行时参数n 的表达式。我能想到的唯一方法如下:
macro macro1(x)
y=length(x.args);
return esc(:(k=$y-1))
end
macro macro2(n)
x="0";
for i=1:n
x="$x+$i"
end
x=parse(x);
return :(@macro1($x))
end
n=rand(1:3)
println(n)
if (n==1)
@macro2(1)
elseif (n==2)
@macro2(2)
elseif (n==3)
@macro2(3)
else
error("expected n in 1:3")
end
println(k)
这里我假设我的运行时 n 将始终在 1-3 范围内。我使用macro2 为n 的这些不同的可能值构建所有可能的表达式,并为它们中的每一个调用外部宏(我在这里用简化的macro1 替换)。对macro1 的调用在if 语句中,因此只有正确的调用(根据运行时n 的值确定)才会实际执行。
虽然这似乎可行,但有没有更有效的方法来实现这一点?
【问题讨论】:
-
通常依赖于运行时的代码生成来自
@generated函数。您应该在the docs 中查看它们 -
我相信
@generated函数只能访问其参数的类型,因此n的值是未知的。 -
你是对的,你
@generated处理参数类型,但你可以“欺骗”系统为你工作。如果您创建一个没有字段但只有一个类型参数n的类型,则可以使用@generated来执行此操作。我没有考虑过你的应用程序,所以我不能说我推荐这种方法,但here's 是一个这样做的例子。请注意,我需要d循环(d是一个函数参数)。因此,我将运行时 valued作为Degree上的类型参数推入,并让@generated在Degree{d}上工作 -
丑陋但聪明。我还不能让它在我的情况下工作 - 我认为它在生成函数之前扩展了宏,所以
n仍然只是一个符号。
标签: macros runtime metaprogramming julia