独立类型内建函数

这些内建函数不(更多)关心它们左侧参数的类型。

switch

Note:

该内建函数从 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 matchedValuecase 参数值的比较, 就像 == 操作符。那就只比较标量并且是相同类型的值。因此,诸如 x?switch(1, "r1", "c2", "r2") 就没有意思。就像 x 是非数字值,那么第一个case就会引发错误, 若 x 是数字值,那么第二个case就会引发错误 (除非 x1, 那么就不会在第一个参数之后做更多的比较)。

  • 不像普通的方法调用, switch(...) 的那些参数被评估为确实需要的。比如,在 two()?switch(c1(), r1(), c2(), r2(), c3(), r3()) 中,如果 two() 返回 2c1() 返回 1, 且 c2() 返回 2,那么只有下面的函数会被调用,而且顺序是这样: m()c1()c2()r2()。(很自然地, 参数不被评估可以指向不存在的变量而不会引发错误。) 它保证了 case 参数表达式被从左到右进行评估,直到第一个匹配项被找到。 它也保证了只有属于第一个匹配 caseresult 表达式会被评估。它还保证了如果没有匹配的 case 参数,那么 defaultResult 表达式会被评估。

  • case 参数表达式不需要是常量值,它们可以是任意复杂的表达式。 当然,逻辑在 resultdefaultResultmatchedValue 中也是相同的。

  • case 参数值的类型没有任何限制,比如它们可以是字符串,或数字,或日期等... 但因为 == 操作符的特性,那么在 相同的 switch 中使用不同类型的 case 参数是没有意义的 (请参考之前的解释)。

  • 不像使用 case 指令,那里没有向下通过的行为,也就是说,不需要相等的 break 指令。

Note:

如果需要对布尔值进行switch操作,那么应该使用 then 内建函数 来代替,比如 matchedBoolean?then(whenTrue, whenFalse)

Note:

如果需要在 case 参数中进行任意的逻辑测试来代替简单的相等比较,那么可以这么来做 (这里我们测试范围): true?switch(priority <= 1, "low", priority == 2, "medium", priority >= 3, "high")