这些内建函数不(更多)关心它们左侧参数的类型。
switch
该内建函数从 FreeMarker 2.3.23 版本开始可用。
这是
switch
-case
-default
指令 的基本内联(表达式)版本。它的通用版本就像
matchedValue?switch(case1,
result1,
case2,
result2, ...
caseN,
resultN,
defaultResult)
,这里的
defaultResult
可以被忽略。比如:
<#list ['r', 'w', 'x', 's'] as flag> ${flag?switch('r', 'readable', 'w' 'writable', 'x', 'executable', 'unknown flag: ' + flag)} </#list>
readable writable executable unknown flag: s
也就是说, switch
会找到第一个
case
和参数
(从左到右)值
matchedValue
相等,
之后返回直接在
case
参数后的
result
参数的值,
如果它没有找到一个相等的
case
,那么就返回
defaultResult
的值,如果没有
defaultResult
参数
(换言之,参数的个数是基数),那么就发生错误中止模板处理。
更多细节:
-
The comparison of
matchedValue
和case
参数值的比较, 就像==
操作符。那就只比较标量并且是相同类型的值。因此,诸如x?switch(1, "r1", "c2", "r2")
就没有意思。就像x
是非数字值,那么第一个case就会引发错误, 若x
是数字值,那么第二个case就会引发错误 (除非x
是1
, 那么就不会在第一个参数之后做更多的比较)。 -
不像普通的方法调用,
switch(...)
的那些参数被评估为确实需要的。比如,在two()?switch(c1(), r1(), c2(), r2(), c3(), r3())
中,如果two()
返回2
,c1()
返回1
, 且c2()
返回2
,那么只有下面的函数会被调用,而且顺序是这样:m()
,c1()
,c2()
,r2()
。(很自然地, 参数不被评估可以指向不存在的变量而不会引发错误。) 它保证了case
参数表达式被从左到右进行评估,直到第一个匹配项被找到。 它也保证了只有属于第一个匹配case
的result
表达式会被评估。它还保证了如果没有匹配的case
参数,那么defaultResult
表达式会被评估。 -
case
参数表达式不需要是常量值,它们可以是任意复杂的表达式。 当然,逻辑在result
,defaultResult
和matchedValue
中也是相同的。 -
对
case
参数值的类型没有任何限制,比如它们可以是字符串,或数字,或日期等... 但因为==
操作符的特性,那么在 相同的switch
中使用不同类型的case
参数是没有意义的 (请参考之前的解释)。 -
不像使用
case
指令,那里没有向下通过的行为,也就是说,不需要相等的break
指令。
如果需要对布尔值进行switch操作,那么应该使用
then
内建函数 来代替,比如
matchedBoolean?then(whenTrue,
whenFalse)
。
如果需要在 case
参数中进行任意的逻辑测试来代替简单的相等比较,那么可以这么来做
(这里我们测试范围):
true?switch(priority <= 1, "low", priority == 2,
"medium", priority >= 3, "high")