这些内建函数不(更多)关心它们左侧参数的类型。
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")