Appearance
表达式
在 Tact 中,每个运算符都形成一个表达式,但 Tact 提供了广泛的表达式选择,还有更多内容值得探索。
字面量
字面量代表 Tact 中的值。这些是固定的值——不是变量——你在代码中直接提供的值。所有字面量本身都是表达式。
你还可以直接在字面值上调用定义在某些原始类型上的扩展函数:
solidity
// 在整数字面量上调用为 Int 类型定义的 toString() 函数:
42.toString();
// 在字符串字面量上调用为 String 类型定义的 asComment() 函数:
"Tact is awesome!".asComment();
整数字面量
整数字面量可以用十进制(基数 10)、十六进制(基数 16)、八进制(基数 8)和二进制(基数 2)表示:
- 十进制整数字面量是数字(0-9)的序列。
- 以
0x
(或0X
)开头表示十六进制整数字面量。它们可以包括数字(0-9)和字母 a-f 以及 A-F。注意,字符的大小写不改变其值。因此:0xa = 0xA = 10
和0xf = 0xF = 15
。 - 以
0o
(或0O
)开头表示八进制整数字面量。它们只能包括数字(0-7)。 - 以
0b
(或0B
)开头表示二进制整数字面量。它们只能包括数字 0 和 1。
注意,在 Tact 中,带前导 0
的整数字面量仍被视为十进制,这与 JavaScript/TypeScript 中的表示八进制的前导 0
不同!
整数字面量的一些示例:
solidity
// 十进制,基数 10:
0, 42, 1_000, 020
// 十六进制,基数 16:
0xABC, 0xF, 0x0011
// 八进制,基数 8:
0o777, 0o001
// 二进制,基数 2:
0b01111001_01101111_01110101_00100000_01100001_01110010_01100101_00100000_01100001_01110111_01100101_01110011_01101111_01101101_01100101
有关整数和 Int 类型的更多信息,请参阅专门页面:Integers。
布尔字面量
Bool 类型只有两个字面值:true 和 false。
solidity
true == true;
true != false;
有关布尔值和 Bool 类型的更多信息,请参阅专门章节:Booleans。
字符串字面量
字符串字面量是零个或多个字符,包含在双引号(")中。所有字符串字面量都是 String 类型的对象。
solidity
"foo"
"1234"
// 注意,目前 Tact 字符串中不能有转义字符:
"line \n another"; // 语法错误!参见:https://github.com/tact-lang/tact/issues/25
// 这意味着字符串内的双引号也是禁止的:
"this \"can't be!\""; // 语法错误!
有关字符串和 String 类型的更多信息,请参阅:Primitive types。
null 字面量
null 值用 null 字面量表示。它不是一个标识符,也不指代任何对象。它也不是任何原始类型的实例。相反,null 代表缺乏标识和故意缺乏任何值。
solidity
let var: Int? = null; // 可以持有 null 值的变量
var = 42;
if (var != null) {
var!! + var!!;
}
有关处理 null 的更多信息,请参阅专门页面:Optionals。
标识符
标识符是代码中的一系列字符,用于标识变量、常量、映射和函数,以及 Struct、Message、合约、特征或它们的字段和方法。标识符区分大小写,不加引号。
在 Tact 中,标识符可以包含拉丁小写字母(a-z)、拉丁大写字母(A-Z)、下划线(_)和数字(0-9),但不能以数字开头。标识符与字符串的区别在于,字符串是数据,而标识符是代码的一部分。
注意,原始类型的标识符以大写字母开头。用户定义的复合类型,如 Structs 和 Messages,也必须大写。
实例化
你可以创建以下类型的实例:
- Structs
- Messages
solidity
struct StExample {
fieldInit: Int = 1;
fieldUninit: Int;
}
fun example() {
StExample{ fieldUninit: 2 }; // 实例化时 fieldInit 使用默认值
StExample{ fieldInit: 0, fieldUninit: 2 }; // 设置两个字段的实例
}
字段访问
你可以直接访问以下类型的字段:
- Structs
- Messages
solidity
struct StExample {
fieldInit: Int = 1;
fieldUninit: Int;
}
fun example(): Int {
let struct: StExample = StExample{ fieldUninit: 2 }; // 实例化
struct.fieldInit; // 访问字段
return struct.fieldUninit; // 从函数返回字段值
}
扩展函数调用
扩展函数仅在特定类型上定义。它们的调用类似于许多其他语言中的方法调用:
solidity
42.toString(); // toString() 是在 Int 类型上定义的标准库函数
静态函数调用
在函数体的任何地方,都可以调用全局静态函数或合约的内部函数:
solidity
contract ExampleContract {
init() {}
receive() {
now(); // now() 是标准库的静态函数
let expiration: Int = now() + 1000; // 操作和变量声明
expiration = self.answerQuestion(); // 内部函数
}
fun answerQuestion(): Int {
return 42;
}
}
initOf
表达式 initOf 计算合约的初始状态(StateInit):
solidity
// 合约 init() 函数的参数值
// ↓ ↓
initOf ExampleContract(42, 100); // 返回一个 Struct StateInit{}
// ---------------
// ↑
// 合约名称
其中 StateInit 是一个内置的 Struct,包括:
字段 | 类型 | 描述 |
---|---|---|
code | Cell | 合约的初始代码(编译后的字节码) |
data | Cell | 合约的初始数据(合约 init() 函数的参数) |