跳到主要内容

类型

信息

FunC 文档最初由 @akifoq 编写。

FunC 有以下内置类型。

原子类型

  • int 是 257 位有符号整数的类型。默认情况下,启用溢出检查,会导致整数溢出异常。
  • cell 是 TVM cell的类型。TON 区块链中的所有持久数据都存储在cell树中。每个cell最多有 1023 位任意数据和最多四个对其他cell的引用。cell在基于堆栈的 TVM 中用作内存。
  • slice 是cell切片的类型。cell可以转换成切片,然后可以通过从切片加载数据位和对其他cell的引用来获得cell中的数据。
  • builder 是cell构建器的类型。数据位和对其他cell的引用可以存储在构建器中,然后构建器可以最终化为新cell。
  • tuple 是 TVM 元组的类型。元组是有序集合,最多包含 255 个组件,这些组件的值类型可能不同。
  • cont 是 TVM continuation的类型。Continuations 用于控制 TVM 程序执行的流程。从 FunC 的角度来看,它是相当低层级的对象,尽管从概念上讲相当通用。

请注意,上述任何类型都只占用 TVM 堆栈中的单个条目。

没有布尔类型

在 FunC 中,布尔值被表示为整数;false 表示为 0true 表示为 -1(二进制表示为 257 个一)。逻辑运算作为位运算执行。当检查条件时,每个非零整数都被视为 true 值。

Null值

通过 TVM 类型 Null 的值 null,FunC 表示某些原子类型的值缺失。标准库中的一些原语可能被类型化为返回原子类型,并在某些情况下实际返回 null。其他原语可能被类型化为接受原子类型的值,但也可以与 null 值一起正常工作。这种行为在原语规范中明确说明。默认情况下,禁止 null 值,这会导致运行时异常。

这样,原子类型 A 可能被隐式转换为类型 A^?,也就是 Maybe A(类型检查器对这种转换无感知)。

Hole类型

FunC 支持类型推断。类型 _var 表示类型“holes”,稍后可以在类型检查期间用某些实际类型填充。例如,var x = 2; 是变量 x 等于 2 的定义。类型检查器可以推断出 x 的类型为 int,因为 2 的类型为 int,赋值的左右两边必须类型相等。

复合类型

类型可以组合成更复杂的类型。

函数类型

形式为 A -> B 的类型表示具有指定域和陪域的函数。例如,int -> cell 是一个函数类型,它接受一个整数参数并返回一个 TVM cell。

在内部,这种类型的值被表示为continuations。

张量类型

形式为 (A, B, ...) 的类型本质上表示有序的值集合,这些值的类型为 AB...,它们一起占用多个 TVM 堆栈条目。

例如,如果函数 foo 的类型为 int -> (int, int),这意味着该函数接受一个整数并返回一对整数。

调用此函数可能看起来像 (int a, int b) = foo(42);。在内部,该函数消耗一个堆栈条目并留下两个。

请注意,从低层级角度来看,类型 (int, (int, int)) 的值 (2, (3, 9)) 和类型 (int, int, int) 的值 (2, 3, 9),在内部以三个堆栈条目 239 的形式表示。对于 FunC 类型检查器,它们是不同类型的值。例如,代码 (int a, int b, int c) = (2, (3, 9)); 将无法编译。

张量类型的特殊情况是cell类型 ()。它通常用于表示函数不返回任何值或没有参数。例如,函数 print_int 的类型将为 int -> (),而函数 random 的类型为 () -> int。它有一个唯一的inhabitant (),它占用 0 个堆栈条目。

类型 (A) 被类型检查器视为与 A 相同的类型。

元组类型

形式为 [A, B, ...] 的类型表示在编译时已知长度和组件类型的 TVM 元组。例如,[int, cell] 是一个元组类型,其长度恰好为 2,其中第一个组件是整数,第二个是cell。[] 是空元组的类型(具有唯一的inhabitant——空元组)。请注意,与cell类型 () 相反,[] 的值占用一个堆栈条目。

带有类型变量的多态

FunC拥有支持多态函数的 Miller-Rabin 类型系统。例如,以下是一个函数:

forall X -> (X, X) duplicate(X value) {
return (value, value);
}

是一个多态函数,它接受一个(单堆栈条目)值并返回这个值的两个副本。duplicate(6) 将产生值 6 6,而 duplicate([]) 将产生两个空元组 [] [] 的副本。

在这个例子中,X 是一个类型变量。

有关此主题的更多信息,请参阅函数部分。

用户定义类型

目前,FunC 不支持定义除上述类型构造之外的类型。

类型宽度

您可能已经注意到,每种类型的值都占用一定数量的堆栈条目。如果所有该类型的值都占用相同数量的条目,则该数字称为类型宽度(type width)。目前只能为具有固定且预先知道的类型宽度的类型定义多态函数。