TL模板类型
partial-app-decl ::= partial-type-app-decl | partial-comb-app-decl
partial-type-app-decl ::= boxed-type-ident subexpr { subexpr } ; | boxed-type-ident < expr { , expr } > ;
partial-comb-app-decl ::= combinator-id subexpr { subexpr };
根据最初的设计,模板必须用于替换构造函数或多态类型的前几个或全部可选参数中的具体值。例如,如果某个类型Tuple int 10经常被使用,您可以为其声明一个模板,这将自动生成相应的构造函数。在使用此类构造函数时,可能没有地方可以传递int类型或元组大小10。类似地,最初的计划是为 `int`、`int` 等类型声明模板,Vector int以便Vector string为每种正在使用的向量类型生成构造函数。这些构造函数使得在反序列化期间能够确定正在传输的数组类型。
现在不使用模板。而是使用相同的通用构造函数(例如vector {t:Type} [t] = Vector t),可选参数的值从结果的类型推断出来(如果我们已经从模式中知道在Vector int反序列化期间此位置必须有一个,我们就知道我们将看到通用vector构造函数,其中t等于int)。
这种方法的优点在于,无需Vector SomeType预先为所有可能的类型定义模板,从而为每种情况生成各自的构造函数。然而,它也存在一个缺点。如果有人想将一个带有特定类型的值的序列化结果Vector int作为另一个类型的值的序列化结果进行传递Object,那么在序列化过程中就会出现问题:在看到通用vector构造函数并读取向量长度之后,我们无法确定接下来应该接收哪种类型的值。
理论上,这个问题可以通过使用构造函数的完整形式(@vector)来解决vector(它会自动定义,不同之处在于所有可选参数都变成了必需参数),或者通过定义来解决。
对象 X:类型 X = 类型化对象
并且需要显式传递对象类型。两种情况下都需要类型序列化。