Velocity 是一个模板引擎,而不是一种适当的编程语言,因此要掌握它的工作原理有点困难。
宏不像 Java 或 C 中的函数,这意味着调用宏不会在堆栈上为局部变量创建新段;速度与上下文一起工作,大多数时候只有一个全局上下文。
尽管如此,还是有两种处理局部变量的方法:
- 有一个
velocimacro.context.localscope
配置参数可以防止从宏中更改全局变量;请注意,此设置已弃用,将在 Velocity 2.0 中删除
- 如果启用配置参数,则可以将该
$macro
变量用作私有变量的本地容器macro.provide.scope.control
尽管如此,还有另一个问题会阻止您的代码正确运行:Velocity 宏主要作为 call-by-macro 扩展工作,这意味着传递给宏的主体不会先被评估,然后再传递给宏;它将在执行嵌套宏时动态评估。代码的行为如下:
#macro(Alpha)
#set($macro.p = 1) -> $macro refers to Alpha
$p -> $p will always be 0, since we're changing a local variable
$macro.p -> 1 here
$bodyContent -> Here $p is used, and 0 is printed
#@Beta()
$macro.p -> it is 1 now, but when this line will be actually evaluated, $macro will refer to Beta, so 2 will be printed
$bodyContent -> It's the content of the Beta macro, which triggers an infinite recursion; it's not $p as above
#end
#end
#macro(Beta)
#set($macro.p = 2) -> $macro refers to Beta
$macro.p -> 2 here
$bodyContent -> the $bodyContent that was passed into the $bodyContent is evaluated now, so it causes a recursion
#end
#set($p = 0)
#@Alpha()
$p -> Global variable
#end