blob: b8e717e3934b32769ad26678689c17923ebed38a [file] [log] [blame]
<!doctype html>
<!-- Generated by FreeMarker/Docgen from DocBook -->
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>Type independent built-ins - Apache FreeMarker Manual</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="Apache FreeMarker Manual">
<meta property="og:title" content="Type independent built-ins">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/ref_builtins_type_independent.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/ref_builtins_type_independent.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1707770044859">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js"></script>
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="https://freemarker.apache.org/docs/">
<meta itemprop="name" content="Apache FreeMarker Manual">
<!--[if lte IE 9]>
<div class="oldBrowserWarning" style="display: block">
Unsupported web browser - Use a modern browser to view this website!
</div>
<![endif]--> <div class="oldBrowserWarning">
Unsupported web browser - Use a modern browser to view this website!
</div>
<div class="header-top-bg"><div class="site-width header-top"><div id="hamburger-menu" role="button"></div> <div class="logo">
<a href="https://freemarker.apache.org" role="banner"><img itemprop="image" src="logo.png" alt="FreeMarker"></a> </div>
<ul class="tabs"><li><a href="https://freemarker.apache.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="https://freemarker.apache.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/projects/FREEMARKER" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="https://freemarker.apache.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="search-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"> <div class="breadcrumbs">
<ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="ref.html"><span itemprop="name">Template Language Reference</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="ref_builtins.html"><span itemprop="name">Built-in Reference</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="ref_builtins_type_independent.html"><span itemprop="name">Type independent built-ins</span></a></li></ul> </div>
<div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width">
<div class="content-wrapper">
<div id="table-of-contents-wrapper" class="col-left">
<script>var breadcrumb = ["Apache FreeMarker Manual","Template Language Reference","Built-in Reference","Type independent built-ins"];</script>
<script src="toc.js?1707770044859"></script>
<script src="docgen-resources/main.min.js?1707770044859"></script>
</div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="ref_builtins_loop_var.html"><span>Previous</span></a><a class="paging-arrow next" href="ref_builtins_expert.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="ref_builtins_type_independent" itemprop="headline">Type independent built-ins</h1>
</div></div><p>These are the built-ins that don&#39;t care (much) about the type of
their left hand argument.</p>
<h2 class="content-header header-section2" id="ref_builtin_switch">switch</h2>
<div class="callout note">
<strong class="callout-label">Note:</strong>
<p>This built-in exists since FreeMarker 2.3.23.</p>
</div>
<p>This is basically the in-line (expression) version of the
<a href="ref_directive_switch.html"><code>switch</code>-<code>case</code>-<code>default</code>
directives</a>. Its generic format is like
<code class="inline-code"><em class="code-color">matchedValue</em>?switch(<em class="code-color">case1</em>,
<em class="code-color">result1</em>,
<em class="code-color">case2</em>,
<em class="code-color">result2</em>, ...
<em class="code-color">caseN</em>,
<em class="code-color">resultN</em>,
<em class="code-color">defaultResult</em>)</code>, where
<code class="inline-code"><em class="code-color">defaultResult</em></code> can be
omitted. Example:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#list [&#39;r&#39;, &#39;w&#39;, &#39;x&#39;, &#39;s&#39;] as flag&gt;
${flag<strong>?switch(&#39;r&#39;, &#39;readable&#39;, &#39;w&#39; &#39;writable&#39;, &#39;x&#39;, &#39;executable&#39;, &#39;unknown flag: &#39; + flag)</strong>}
&lt;/#list&gt;</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body"> readable
writable
executable
unknown flag: s</pre> </div>
<p>That is, <code class="inline-code">switch</code> will find the first
<code class="inline-code"><em class="code-color">case</em></code> parameter (left
to right) whose value equals to
<code class="inline-code"><em class="code-color">matchedValue</em></code>, then it
returns the value of the
<code class="inline-code"><em class="code-color">result</em></code> parameter
that&#39;s directly after that
<code class="inline-code"><em class="code-color">case</em></code> parameter. If it
doesn&#39;t find an equal
<code class="inline-code"><em class="code-color">case</em></code>, then it will
return the value of the
<code class="inline-code"><em class="code-color">defaultResult</em></code>, or if
there&#39;s no
<code class="inline-code"><em class="code-color">defaultResult</em></code>
parameter (i.e., if the number of parameters is even) then it stops
the template processing with error.</p>
<p>Further details:</p>
<ul>
<li>
<p>The comparison of
<code class="inline-code"><em class="code-color">matchedValue</em></code> to
the <code class="inline-code"><em class="code-color">case</em></code> parameter
value behaves exactly like <a href="dgui_template_exp.html#dgui_template_exp_comparison">the <code>==</code>
operator</a>. Hence it only compares scalars and only
same-type values. Thus, something like <code class="inline-code">x?switch(1,
&quot;r1&quot;, &quot;c2&quot;, &quot;r2&quot;)</code> doesn&#39;t make sense, as if
<code class="inline-code">x</code> is non-numerical then the first case will
cause error, and if <code class="inline-code">x</code> is numerical then the
second case will cause error (unless <code class="inline-code">x</code> is
<code class="inline-code">1</code>, as then we won&#39;t do further comparisons
after the first one).</p>
</li>
<li>
<p>Unlike with normal method calls, only those parameters of
<code class="inline-code">switch(<em class="code-color">...</em>)</code> are
evaluated that are indeed needed. For example, in
<code class="inline-code">two()?switch(c1(), r1(), c2(), r2(), c3(),
r3())</code>, if <code class="inline-code">two()</code> returns
<code class="inline-code">2</code>, <code class="inline-code">c1()</code> returns
<code class="inline-code">1</code>, and <code class="inline-code">c2()</code> returns
<code class="inline-code">2</code>, then only the following functions will be
called, and in this order: <code class="inline-code">m()</code>,
<code class="inline-code">c1()</code>, <code class="inline-code">c2()</code>,
<code class="inline-code">r2()</code>. (Naturally, arguments that aren&#39;t
evaluated can refer to missing variables without causing error.)
It&#39;s guaranteed that the
<code class="inline-code"><em class="code-color">case</em></code> parameter
expressions are evaluated left to right, and only until the
first match was found. It&#39;s also guaranteed that only the
<code class="inline-code"><em class="code-color">result</em></code> expression
that belongs to the first matching
<code class="inline-code"><em class="code-color">case</em></code> will be
evaluated. It&#39;s also guaranteed that the
<code class="inline-code"><em class="code-color">defaultResult</em></code>
expression will only be evaluated if there was no matching
<code class="inline-code"><em class="code-color">case</em></code>
parameter.</p>
</li>
<li>
<p>The <code class="inline-code"><em class="code-color">case</em></code>
parameter expressions need not be constant values, they can be
arbitrary complex expressions. Of course, the same goes for and
the <code class="inline-code"><em class="code-color">result</em></code>,
<code class="inline-code"><em class="code-color">defaultResult</em></code>, and
<code class="inline-code"><em class="code-color">matchedValue</em></code>.</p>
</li>
<li>
<p>There&#39;s no restriction regarding the type of the
<code class="inline-code"><em class="code-color">case</em></code> parameter
values, like they can be strings, or numbers, or dates, etc.
However, because of how the <code class="inline-code">==</code> operator
works, it doesn&#39;t make sense to use
<code class="inline-code"><em class="code-color">case</em></code> parameters of
different types inside the <em>same</em>
<code class="inline-code">switch</code> (see earlier why).</p>
</li>
<li>
<p>Unlike with the <a href="ref_directive_switch.html"><code>case</code>
directive</a>, there&#39;s no fall-through behavior there, that
is, there&#39;s no need for an equivalent of the
<code class="inline-code">break</code> directive.</p>
</li>
</ul>
<div class="callout note">
<strong class="callout-label">Note:</strong>
<p>If you need to switch by a boolean value, you should use the
<a href="ref_builtins_boolean.html#ref_builtin_then"><code>then</code>
built-in</a> instead, like
<code class="inline-code"><em class="code-color">matchedBoolean</em>?then(<em class="code-color">whenTrue</em>,
<em class="code-color">whenFalse</em>)</code>.</p>
</div>
<div class="callout note">
<strong class="callout-label">Note:</strong>
<p>If you need to do arbitrary logical tests instead of simple
equality comparisons at the
<code class="inline-code"><em class="code-color">case</em></code> parameters, you
can do something like this (here we tests for ranges):
<code class="inline-code">true?switch(priority &lt;= 1, &quot;low&quot;, priority == 2,
&quot;medium&quot;, priority &gt;= 3, &quot;high&quot;)</code></p>
</div>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="ref_builtins_loop_var.html"><span>Previous</span></a><a class="paging-arrow next" href="ref_builtins_expert.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="https://freemarker.apache.org/">What is FreeMarker?</a></li><li><a href="https://freemarker.apache.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="app_faq.html">FAQ</a></li><li><a itemprop="license" href="app_license.html">License</a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a></li></ul></div><div class="column"><h3 class="column-header">Often used / Reference</h3><ul><li><a href="https://try.freemarker.apache.org/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li><li><a href="api/freemarker/core/Configurable.html#setSetting-java.lang.String-java.lang.String-">Configuration settings</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/apache/freemarker">Github project page</a></li><li><a href="https://issues.apache.org/jira/projects/FREEMARKER">Report a bug</a></li><li><a href="https://freemarker.apache.org/report-security-vulnerabilities.html">Report security vulnerability</a></li><li><a href="https://stackoverflow.com/questions/ask?tags=freemarker">Get help on StackOverflow</a></li><li><a href="https://twitter.com/freemarker">Announcements on Twitter</a></li><li><a href="https://freemarker.apache.org/mailing-lists.html">Discuss on mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/apache/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="https://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2024-02-12T20:34:04Z" title="Monday, February 12, 2024 at 8:34:04 PM Greenwich Mean Time">2024-02-12 20:34:04 GMT</time>, for Freemarker 2.3.32 </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2024
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. </p>
</div></div></div></body>
</html>