原文请移步《FreeMarker中文手册:数值和类型》
数值
简介
这里假设你已经阅读完入门章节的内容了。
理解数值和类型的概念是理解数据模型的关键和基础。然而,数值和类型的概念并不局限于数据模型,下面你就会看到了。
什么是数值
这部分对于程序员来说可以直接跳过这,它和程序语言中的数值类型是相似的。
你所知道的来自于每天所使用的数字,比如16,0.5 等这些用语就是数值的示例,也就是数字。在计算机语言中,这些用语有着更广泛的含义,比如数值并不一定是数字值,看下面这个数据模型:
(root) | +- user = "Big Joe" | +- today = Jul 6, 2007 | +- todayHoliday = false | +- lotteryNumbers | | | +- (1st) = 20 | | | +- (2st) = 14 | | | +- (3rd) = 42 | | | +- (4th) = 8 | | | +- (5th) = 15 | +- cargo | +- name = "coal" | +- weight = 40
我们说变量user的数值是”Big Joe”(字符串),today的数值是Jul 6,2007(日期),todayHoilday 的数值是false(布尔值,是/否,这样的值)。lotteryNumbers 的数值是包含20,14,42,8,15 的序列。在这种意义上,lotteryNumbers 是多值的,它包含多个数值(如其中的第二项是14),但是lotteryNumbers 本身还是单值。它像一个装有很多东西的盒子,整个盒子被看做是独立的。最后有一个数值cargo,它是一个哈希表(也可以看做是盒子)。所以数值就是存储在变量中的(在user,cargo 或cargo.name 中)东西。但是不需要存储的数值也可以称之为数值,比如这里的数字100:
<#if cargo.weight < 100>Light cargo
当模板被执行时,计算的临时结果也称为数值,比如20+120(它会打印120):
${cargo.weight / 2 + 100}
这最后一种的解释:两个数40(货物的重量)和2 相除的结果是20,这是一个新计算出的数值。把它和100 相加,那么120 就出来了,接着就打印出来了(${…} ),接着模板继续向下执行直到所有结果都计算出来。
现在你应该能体会到数值这个词的含义了,不仅仅是数字的值。
什么是类型
数值中非常重要的一个概念就是类型。比方说,变量user 的类型是字符串,lotteryNumbers 的类型是序列。数值的类型非常重要,因为它决定了这些数值可以在哪里使用的最大限度。比如${user/2}就是错误的,但是${cargo.weight/2}就能计算出结果20,除法仅对数字值有效,而不能作用于字符串。仅当cargo 是一个哈希表时cargo.name 可以使用。也可以用<#list …>仅仅来遍历序列。 <#if …>指令的条件condition 只能是布尔值等。
注意:这里说一点点术语:称 “布尔”或“布尔值”或“布尔类型”都是相同的含义。
数值同时也可以含有多种类型,尽管这样很少使用。看下面这个数据模型mouse,就又是字符串又是哈希表。
(root) | +- mouse = "Yerri" | +- age = 12 | +- color = "brown"
如果用上面的数据模型合并到模板中,就该这么来写:
${mouse} <#-- 用 mouse 作为字符串 --> ${mouse.age} <#-- 用 mouse 作为哈希表 --> ${mouse.color} <#-- 用 mouse 作为哈希表 -->
它的输出内容为:
Yerri 12 brown
数据模型是哈希表
注意观察每个你已经知道的数据模型:被”(root)”标识的内容就是哈希表类型的数值。当书写如user 这样的代码,那就意味着想要把”user”变量存储在哈希表的根上。而如果代码是:root.user,也没有名为”root”的变量,那么这就没有任何作用。
某些人也许会被这种数据模型的例子所困惑,也就是说,根哈希表包含更多的哈希表或序列(如lotteryNumbers 和cargo)。其他就没有更特殊的了。哈希表包含其他变量,那些变量包含数值,数值可以是字符串,数字等,当然也可以是哈希表或序列。最初我们解释过,就像字符串和数字,序列或哈希表也是数值。
类型
简介
支持的类型有:
标量:
字符串
数字
布尔值
日期
容器:
哈希表
序列
集
子程序:
方法和函数
用户自定义指令
其它/很少使用:
节点
标量
标量是最基本,最简单的数值类型,它们可以是:
字符串:简单的文本,例如:产品的名称。
如果想在模板中直接给出字符串的值,而不是使用数据模型中的变量,那么将文本写在引号内即可,比如”green mouse”或者’ green mouse ’。
数字:例如:产品的价格。整数和非整数是不区分的,只有单一的数字类型。比如使用了计算器,计算3/2 的结果是1.5 而不是1。
如果要在模板中直接给出数字的值,可以这么来写:150,-90.05,或者0.001。
布尔值:布尔值代表了逻辑上的对或错(是或否)。例如:用户到底是否登录了。
典型的应用是使用布尔值作为if 指令的条件,比如<#if loggedIn>…或者<#if price==0>…,后面这个price==0 部分的结果就是布尔值。在模板中可以使用保留字true 和false 来指定布尔值。
日期:日期变量可以存储和日期/时间相关的数据。一共有三种变化。
精确到天的日期(通常指的是“日期”),比如April 4, 2003
每天的时间(不包括日期部分),比如10:19:18 PM。时间的存储精确到毫秒。
日期-时间(也称作“时间戳”),比如April 4, 2003 10:19:18 PM。时间部分的存储精确到毫秒。
不幸的是,受到Java 平台的限制,FreeMarker 是不能决定日期的部哪分来使用(也就是说,是日期-时间格式,每天的时间格式等)。这个问题的解决方法是高级主题了,后面的章节将会讨论到。在模板中直接定义日期数值是可以的,但这也是高级主题,后面的章节将会讨论到。
要记住,FreeMarker 区别字符串,数字和布尔值,所以字符串”150”和数字150 是完全不同的两种数值。数字持有的是数字的值,布尔值表达的是逻辑上的对或错。字符串可以是任意字符的序列。
容器
这些值存在的目的是为了包含其他变量,它们仅仅作为容器。被包含的变量通常是子变量。容器的类型有:
哈希表:每个子变量都可以通过一个唯一的名称来查找,这个名称是不受限制的字符串。哈希表并不确定其中子变量的顺序,也就是说没有第一个变量,第二个变量
这样的说法,变量仅仅是通过名称来访问的。(就像Java 语言中的HashMap 一样,是实现了Hash 算法的Map,不记录内部元素的顺序,仅仅通过名称来访问)
序列:每个子变量通过一个整数来标识。第一个子变量的标识符是0,第二个是1,第三个是2,这样来类推,而且子变量是有顺序的。这些数字通常被称为是子变量的索引。序列通常比较密集,也就是所有的索引,包括最后一个子变量的,它们和子变量都是相关联的,但不是绝对必要的。子变量的数值类型也并不需要完全一致。
集: 从模板设计者角度来看,集是有限制的序列。不能获取集的大小,也不能通过索引取出集中的子变量,但是它们仍然可以通过list 指令来遍历。
要注意一个数值也可有多种类型,对于一个数值可能存在哈希表和序列这两种类型,这时,该变量就支持索引和名称两种访问方式。不过容器基本是当作哈希表或者序列来使用的,而不是两者同时使用。
尽管存储在哈希表,序列(集)中的变量可以是任意类型的,这些变量也可以是哈希表,序列(集)。这样就可以构建任意深度的数据结构。
数据模型本身(最好说成是它的根)也是哈希表。
子程序
方法和函数
一个值是方法或函数的时候那么它就可以计算其他值,结果取决于传递给它的参数。这部分是对程序员来说的:方法/函数是第一类值,就像函数化的编程语言。也就是说函数/方法也可以是其他函数或方法的参数或者返回值,并可以把它们定义成变量。
假设程序员在数据模型中放置了一个方法变量avg,那么它就可以被用来计算数字的平均值。给定3 和5 作为参数,访问avg 时就能得到结果4。
方法的使用后续章节会有解释,下面这个示例会帮助我们理解方法的使用:
The average of 3 and 5 is: ${avg(3, 5)} The average of 6 and 10 and 20 is: ${avg(6, 10, 20)} The average of the price of a python and an elephant is: ${avg(animals.python.price, animals.elephant.price)}
可以得到如下的输出:
The average of 3 and 5 is: 4 The average of 6 and 10 and 20 is: 12 The average of the price of a python and an elephant is: 4999.5
那么方法和函数有什么区别呢?这是模板作者所关心的,它们没有关系,但也不是一点关系都没有。方法是来自于数据模型(它们反射了Java 对象的方法),而函数是定义在模板内的(使用了函数指令-这也是高级主题),但二者可以用同一种方式来使用。
用户自定义指令
用户自定义指令(换句话说,就是FreeMarker 的标签)这种类型的值也是一种子程序,一种可以复用的模板代码段。但这也是高级主题,我们在后续章节中会详细解释。
这部分是对程序员来说的:用户自定义指令(比如宏),也是第一类值,就像函数/方法一样。
这里仅仅对用户自定义指令有一个认识即可(如果现在还不能理解可以先忽略它)。假设现在有一个变量,box,它的值是用户自定义的指令,用来打印一些特定的HTML 信息,这个指令定义了一个标题和其中的信息。
<@box title="Attention!"> Too much copy-pasting may leads to maintenance headaches.
函数/方法和用户自定义指令的比较
这部分内容也是对高级用户来说的(如果你还不能理解可以先忽略它)。如果要使用函数/方法或自定义指令去实现一些东西的时候,二者之间的选择是两难的。按经验来说,如果能够实现,请先用自定义指令而不要用函数/方法。指令的特征如下:
输出(返回值)的是标记(HTML,XML 等)。主要原因是函数的返回结果可以自动进行XML 转义(这是因为${…}的特性),而用户自定义指令的输出则不是(这是因为<@...>的特性所致,它的输出假定为是标记,因此就不再转义)。
副作用也是很重要的一点,它没有返回值。例如一个指令的目的是往服务器日志中添加一个条目。(事实上你不能得到自定义指令的返回值,但有些反馈的类型是有可能设置非本地变量的)
会进行流程的控制(就像list 或if 指令那样),但是不能在函数/方法上这么做。在模板中,FreeMarker 不知道的Java 对象的方法通常是可以作为方法来使用的,而不用考虑Java 对象方法本身的特性,因为在这里没有其他的选择。
其它
节点
节点变量代表了树状结构中的一个节点,而且通常是配合XML 格式来处理的,这是专业而且更高级的主题。
这里我们仅对高级用户进行一个概要说明:节点和存储在其他节点中的序列很相似,通常也被当作为子节点。节点存储它所在的容器节点的引用,也就是父节点。节点的主要作用是拓扑信息。其它数据必须通过使用多类型的值来存储。就像一个值可以同时是一个节点和一个数字,这样它存储的数字可以作为如支付额来使用。除了拓扑信息,节点也可以存储一些元信息(即metadata,译者注):如节点名称,它的类型(字符串),命名空间(作为字符串)。若一个节点象征XHTML 文档中的h1 元素,那么它的名字可以是”h1”,类型可以是”element”,命名空间可以是”http://www.w3.org/1999/xhtml”。但对于数据模型设计者来说,这些元信息,还有如何来使用它们又有什么意义呢。检索拓扑信息和元信息的方法将会在后续章节中来说明(这里你可以先不用理解它们)。
来自 yshjava的个人博客主页 FreeMarker中文手册:数值和类型
上一篇:《FreeMarker中文手册:模板一览》
FreeMarker中文版手册由南磊翻译(译者联系方式为:nanlei1987@gmail.com 或http://weibo.com/nanlei1987),官网地址http://www.freemarker.org
相关推荐
- **数值和类型**:讲述了在FreeMarker中使用的数据类型,包括基本数据类型和复杂数据类型。 - **模板**:涵盖了模板的整体结构、指令使用、表达式和插值处理等关键部分。 - **其它**:提供了如何自定义指令、在模板...
- 数值和类型章节涉及了在模板开发中会用到的类型和基本数值操作。 - 模板章节详细介绍了模板的总体结构、指令的使用和表达式的基本语法。 - 在数据模型部分,讲解了如何构建数据模型以及模型中的标量、容器、方法等...
进一步地,了解"数值和类型"章节,这对于理解和处理模板中的数据至关重要。 **3. 文档规约** 手册可能包含对FreeMarker语法的详细描述,包括模板元素(如变量、控制结构、内置函数等)、指令的使用方法,以及如何...
##### 第二章:数值和类型 - **2.1 基本内容**:介绍了数值类型的基础知识,包括整数、浮点数等。 - **2.2 类型**:深入探讨了FreeMarker中的各种类型,包括数值、字符串、日期等。 ##### 第三章:模板 - **3.1 ...
第二章 数值和类型 2.1 基本内容 FreeMarker支持各种数值类型,包括整数、浮点数和布尔值。表达式的结果会自动转换为适当类型,但也有时候需要显式转换。例如,数字运算可能需要确保所有操作数都是同一类型,否则...
**第二章 数值和类型** - **2.1 基本内容:**涵盖了FreeMarker中的基本数据类型及其使用方法。 - **2.2 类型:**深入探讨了FreeMarker支持的不同数据类型,如字符串、数字、日期等,并讨论了它们之间的转换规则。 *...
### FreeMarker开发手册知识点概述 #### 一、FreeMarker概览 **1.1 什么是FreeMarker** - **定义**: FreeMarker是一个用Java编写的模板引擎,它支持动态页面生成,能够将数据模型与表现层分离,使得Web开发更加灵活...
数值和类型章节阐述了在模板中使用的数据类型,包括基本类型如字符串、数字和日期等,以及如何处理这些类型的数据。 模板章节则深入讲解了模板的总体结构、指令、表达式以及插值的概念和用法。模板指令是FreeMarker...
- **基本内容**:讲解了 FreeMarker 中的数值和类型的基本概念,包括整数、浮点数等。 - **类型**:详细介绍了 FreeMarker 支持的各种数据类型,如 String、Number、Boolean 等。 ##### 3. 模板 - **总体结构**...
手册分为四个部分,第一部分是模板开发指南,其中包含了模板开发的入门知识、数值和类型处理、模板的总体结构和指令使用、表达式的编写及插值方式。 在模板开发入门章节中,我们了解到模板和数据模型的关系,模板是...
这一章深入探讨了FreeMarker中的数值处理和类型系统,包括数值类型、字符串、布尔值、列表、映射等,以及它们之间的转换规则和操作方法。 继续阅读手册,你将了解到更多关于FreeMarker的高级特性,如模板继承、宏、...