TL-B 类型
此信息属于非常底层的内容,对新手来说可能难以理解。 因此,您可以稍后再阅读。
在本节中,我们将分析复杂和非传统的类型化语言二进制(TL-B)结构。开始之前,我们建议先阅读此文档,以更熟悉该主题。
Either
left$0 {X:Type} {Y:Type} value:X = Either X Y;
right$1 {X:Type} {Y:Type} value:Y = Either X Y;
Either类型用于可能出现两种结果类型之一的情况。在这种情况下,类型选择取决于所示的前缀位。如果前缀位是0,则序列化左类型,而如果使用1前缀位,则序列化右类型。
例如,在序列化消息时使用它,当消息体要么是主cell的一部分,要么链接到另一个cell。
Maybe
nothing$0 {X:Type} = Maybe X;
just$1 {X:Type} value:X = Maybe X;
Maybe类型与可选值一起使用。在这些情况下,如果第一位是0,则不会序列化该值(实际上被跳过),而如果值是1,则会被序列化。
Both
pair$_ {X:Type} {Y:Type} first:X second:Y = Both X Y;
Both类型变体仅与普通对一起使用,两种类型依次序列化,没有条件。
Unary
Unary函数类型通常用于动态大小的结构,例如hml_short。
Unary提供两个主要选项:
unary_zero$0 = Unary ~0;
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
Unary序列化
通常,使用unary_zero
变体相当简单:如果第一位是0,则Unary反序列化的结果为0。
然而,unary_succ
变体更复杂,因为它是递归加载的,具有~(n + 1)
的值。这意味着它会顺序调用自身,直到达到unary_zero
。换句话说,所需的值将等于一连串单位的数量。
例如,让我们分析位串110
的序列化。
调用链如下:
unary_succ$1 -> unary_succ$1 -> unary_zero$0
一旦到达unary_zero
,值就会返回到序列化位串的末尾,类似于递归函数调用。
现在,为了更清楚地理解结果,让我们检索返回值路径,显示如下:
0 -> ~(0 + 1) -> ~(1 + 1) -> 2
,这意味着我们将110
序列化为Unary 2
。
Unary反序列化
假设我们有Foo
类型:
foo$_ u:(Unary 2) = Foo;
根据上述内容,Foo
将被反序列化为:
foo u:(unary_succ x:(unary_succ x:(unnary_zero)))
Hashmap
Hashmap复杂类型用于存储FunC智能合约代码中的字典(dict
)。
以下TL-B结构用于序列化具有固定键长度的Hashmap:
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
{n = (~m) + l} node:(HashmapNode m X) = Hashmap n X;
hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
right:^(Hashmap n X) = HashmapNode (n + 1) X;
hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;
unary_zero$0 = Unary ~0;
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
hme_empty$0 {n:#} {X:Type} = HashmapE n X;
hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X;
这意味着根结构使用HashmapE
及其两种状态之一:包括hme_empty
或hme_root
。