12.1. #set

#set 指令用来为引用设置相应的值。值可以被值派给变量引用或者是属性引用,而且赋值要在括号里括起来。

#set( $primate = "monkey" )
#set( $customer.Behavior = $primate )

赋值的左边必须是一个变量应用或者是属性引用。右边可以是下面的类型之一:

  • 变量引用
  • 字面字符串
  • 属性引用
  • 方法引用
  • 字面数字
  • 数组列表

这些例子演示了上述的每种类型:

#set( $monkey = $bill ) ## variable reference
#set( $monkey.Friend = "monica" ) ## string literal
#set( $monkey.Blame = $whitehouse.Leak ) ## property reference
#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference
#set( $monkey.Number = 123 ) ##number literal
#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList

注意:最后一个例子中,在方括号[..] 中定义的项目可以被ArrayList 类定义的方法访问。比如,你可以使用$monkey.Say.get(0)访问上述的第一个元素。

右边也可以是一个简单的算术表达式:

#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )

如果右边是一个属性或方法引用,取值是NULL,他将不会赋值给左边。通过这种机制将一个存在的引用从上下文中删除是不可能的。这对Velocity的新手可能会混淆。例如:

#set( $result = $query.criteria("name") )
The result of the first query is $result

#set( $result = $query.criteria("address") )
The result of the second query is $result

如果, $query.criteria("name") 放回字符串"bill",而$query.criteria("address") 返回 null,上述VTL 将解释为:

The result of the first query is bill

The result of the second query is bill

这往往会给那些想构建#foreach循环来试图通过属性和方法引用来设置一个引用的新手带来困惑,下面马上通过#if指令测试一下。例如:

#set( $criteria = ["name", "address"] )

#foreach( $criterion in $criteria )

    #set( $result = $query.criteria($criterion) )

    #if( $result )
        Query was successful
    #end

#end

在上面的例子中,依靠$result 的去值来决定查询是否成功恐怕不是英明的做法。当$result 被#set设置后(添加到上下文中),他就不能再被设值为null (从上下文中删除)。

我们对此的解决方法是预设$result 为 false。然后如果 $query.criteria() 调用失败,你就可以检查之。

#set( $criteria = ["name", "address"] )

#foreach( $criterion in $criteria )

    #set( $result = false )
    #set( $result = $query.criteria($criterion) )

    #if( $result )
        Query was successful
    #end

#end

不象其他Velocity 指令, #set 指令没有#end 语句。