templates - Velocity 模板宏中的闭包

标签 templates closures velocity

我有几个像这样的 Velocity 宏:

#macro(Alpha)
  #set($p = 1)
  #@Beta()
    $p             // 1
    $bodyContent
  #end
#end

#macro(Beta $params)
  #set($p = 2)
  $p               // 2
  $bodyContent
#end

我是这样使用它们的:

#set($p = 0)
#@Alpha(...)
  $p               // 3
#end

我相信这是这样呈现的(忽略格式):2, 2, 2

但我想要适当的闭包行为,包括隐藏父作用域名称的更多局部作用域名称。特别是,标记为“3”的 $p 的用法应指代值 0,“2”指代值 2,“1”指代值 1。

给定适当的闭包语义,它将打印:2, 1, 0

有什么方法可以做到这一点,或者有什么方法可以实现自定义指令/修改#macro 指令行为来实现这一点?

最佳答案

Velocity 是一个模板引擎,而不是一种合适的编程语言,因此要理解它的工作原理有点困难。

宏不是 Java 或 C 中的函数,这意味着调用宏不会在堆栈上为局部变量创建一个新段; velocity 与上下文一起工作,大多数时候只有一个全局上下文。

仍然有两种处理局部变量的方法:

  1. velocimacro.context.localscope防止从宏内更改全局变量的配置参数;请注意,此设置已弃用,并将在 Velocity 2.0 中删除
  2. 如果启用 macro.provide.scope.control 配置参数,则可以将 $macro 变量用作私有(private)变量的本地容器

还有另一个问题会阻止您的代码正确运行:Velocity macros work mostly as call-by-macro expansion ,这意味着传递给宏的主体不会先求值,然后再传递给宏;执行嵌套宏时将对其进行动态评估。代码的行为如下:

#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

关于templates - Velocity 模板宏中的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12519289/

相关文章:

java - 如何开始使用速度

java - Apache Velocity 模板文件中出现意外错误

c++ - 可变参数模板类中需要什么前向声明?

C++ 错误 : passing const as 'this' argument

android - 带有 Android Studio 的 IntelliJ Android 代码样式模板删除了字符串中复数前面的空格

swift -3 : closure with escaping and non-escaping behaviour together

javascript - 为什么我们在 JavaScript 中有闭包?

eclipse - eclipse indigo (3.7.x) 的速度编辑器

c++ - CArray 的 ARG_TYPE 是否应该是 const & 或者不是

javascript - Expressjs中间件中定义的静态变量