正如已经看到的,数据模型的基本结构是树状的。 这棵树可以很复杂,并且可以有很大的深度,比如:
(root) | +- animals | | | +- mouse | | | | | +- size = "small" | | | | | +- price = 50 | | | +- elephant | | | | | +- size = "large" | | | | | +- price = 5000 | | | +- python | | | +- size = "medium" | | | +- price = 4999 | +- message = "It is a test" | +- misc | +- foo = "Something"
上图中的变量扮演目录的角色(比如 root,
        animals, mouse,
        elephant, python,
        misc) 被称为 hashes (哈希表或哈希,译者注)。哈希表存储其他变量(被称为 
        子变量),
		它们可以通过名称来查找(比如 "animals",
        "mouse" 或 "price")。
存储单值的变量
        (size, price,
        message 和 foo) 称为
        scalars (标量,译者注)。
如果要在模板中使用子变量,
		那应该从根root开始指定它的路径,每级之间用点来分隔开。要访问 mouse 的
        price ,要从root开始,首先进入到 animals ,之后访问
        mouse ,最后访问 price 。就可以这样来写 
		animals.mouse.price。
另外一种很重要的变量是 sequences (序列,译者注)。
		它们像哈希表那样存储子变量,但是子变量没有名字,它们只是列表中的项。
		比如,在下面这个数据模型中, animals 和
        misc.fruits 就是序列:
(root) | +- animals | | | +- (1st) | | | | | +- name = "mouse" | | | | | +- size = "small" | | | | | +- price = 50 | | | +- (2nd) | | | | | +- name = "elephant" | | | | | +- size = "large" | | | | | +- price = 5000 | | | +- (3rd) | | | +- name = "python" | | | +- size = "medium" | | | +- price = 4999 | +- misc | +- fruits | +- (1st) = "orange" | +- (2nd) = "banana"
要访问序列的子变量,可以使用方括号形式的数字索引下标。
		索引下标从0开始(从0开始也是程序员的传统),那么第一项的索引就是0,
		第二项的索引就是1等等。要得到第一个动物的名称的话,可以这么来写代码 
		animals[0].name。要得到 misc.fruits 
		中的第二项(字符串"banana")可以这么来写 
		misc.fruits[1]。(实践中,通常按顺序遍历序列,而不用关心索引,
		这点会在 后续介绍。)
标量类型可以分为如下的类别:
- 
            字符串:就是文本,也就是任意的字符序列,比如上面提到的 ''m'', ''o'', ''u'', ''s'', ''e''。比如 name和size也是字符串。
- 
            数字:这是数值类型,就像上面的 price。 在FreeMarker中,字符串"50"和数字50是两种完全不同的东西。前者是两个字符的序列 (这恰好是人们可以读的一个数字),而后者则是可以在数学运算中直接被使用的数值。
- 
            日期/时间: 可以是日期-时间格式(存储某一天的日期和时间), 或者是日期(只有日期,没有时间),或者是时间(只有时间,没有日期)。 
- 
            布尔值:对应着对/错(是/否,开/关等值)类似的值。 比如动物可以有一个 protected(受保护的,译者注) 的子变量, 该变量存储这个动物是否被保护起来的值。
总结:
- 
            数据模型可以被看成是树形结构。 
- 
            标量用于存储单一的值。这种类型的值可以是字符串,数字,日期/时间或者是布尔值。 
- 
            哈希表是一种存储变量及其相关且有唯一标识名称的容器。 
- 
            序列是存储有序变量的容器。存储的变量可以通过数字索引来检索,索引通常从0开始。 
还有一些其它更为高级的类型,在这里我们并没有涉及到,比如方法和指令。
