跳转到内容

表达式

Tact 中的每个运算符都能构成一个表达式,但 Tact 还提供了更多的表达式选项供您选择。

Literals

字面表示 Tact 中的值。 这些是固定值,而不是变量,是您在代码中实际提供的。 Tact 中的所有字面量都是表达式本身。

您还可以调用定义在某些 基元类型上的 扩展函数,这些 基元类型 与字面值相对应:

// 在整数字面量上调用为 Int 定义的 toString() 函数:
42.toString();
// 在字符串字面量上调用为 String 定义的 asComment() 函数:
"Tact is awesome!".asComment();

Integer literals

整数字面可以用十进制(基 1010)、十六进制(基 1616)、八进制(基 88)和二进制(基 22)符号书写:

  • 一个 decimal integer 字面量是一串数字(09\mathrm{0 - 9})。

  • 前导 0x\mathrm{0x}(或 0X\mathrm{0X})表示十六进制整数 字面量。 它们可以包括数字(09\mathrm{0 - 9})和字母 af\mathrm{a - f}AF\mathrm{A - F}。 请注意,字符的大小写不会改变其值。 因此:0xa\mathrm{0xa} = 0xA\mathrm{0xA} = 10100xf\mathrm{0xf} = 0xF\mathrm{0xF} = 1515

  • 前导 0o\mathrm{0o}(或 0O\mathrm{0O})表示 octal integer 字面量。 它们只能包括数字 07\mathrm{0 - 7}

  • 前导 0b\mathrm{0b}(或 0B\mathrm{0B})表示 二进制整数 字面量。 它们只能包括数字 0011

一些整数字面的例子

// 十进制,基数 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类型的更多信息,请访问专门页面:整数

Boolean literals

Bool类型只有两个字面值:truefalse

true == true;
true != false

有关布尔和 Bool类型的更多信息,请参阅专门章节:布尔

String literals

字符串字面量是用双引号("”)括起来的零个或多个字符。 所有字符串字面量都是 字符串类型的对象。

"foo";
"1234"

Tact 字符串支持一系列从反斜杠字符开始的转义序列

  • \\ - 字面反斜线
  • \" - 双引号
  • \n - 换行
  • \r - 回车
  • \t - tab
  • \v - 垂直标签
  • \b - 退格
  • \f - 表格供稿
  • \x00\xFF - 代码点,长度必须正好是两个十六进制数字
  • \u0000\uFFFF - Unicode 代码点,长度必须正好是四个十六进制数字
  • \u{0}\u{FFFFFF} - Unicode 代码点,长度可以是 1166 的十六进制数
//
"escape (escape)if (you)can (can)";
//
"this ("litally") works";
// \n
"line \n another line";
// \r
"Shutters \r Like \r This \r One";
// \t
"spacing \t granted!";
// \v
"those \v words \v are \v aligned";
// \b
"rm\b\bcreate!";
// \f
"form \f feed";
// \x00 - \xFF
"this \x22literally\x22 works"; // \x22 表示双引号
// \u0000 - \uFFFF
"danger, \u26A1 high voltage \u26A1"// \u26A1 代表⚡表情符号
// \u{0} - \u{FFFFFF}
"\u{1F602} LOL \u{1F602}"; // \u{1F602} 代表😂表情符号

null literal

值将以null 字面形式写入。它不是标识符,也不指向任何对象。它也不是原始类型的实例。相反,null表示缺乏标识和故意不存在任何价值。

var= null; // variable, which can hold null value
var = 42;
if (var != null) {
var!+ var!!;
}

有关使用 null的更多信息,请访问专门页面:选项

Identifiers

标识符是代码中的一串字符,用于标识变量常量映射函数,以及结构消息契约特质或它们的字段和方法。 标识符区分大小写,不加引号。

在 Tact 中,标识符可以包含拉丁小写字母 (a-z)、拉丁大写字母 (A-Z)、下划线 (_)和数字 (09\mathrm{0 - 9}),但不能以数字开头。 标识符与 [字符串](#string-literals)的区别在于,字符串是数据,而标识符是代码的一部分。

请注意,当基元类型的标识符以大写字母开头时。 已使用定义的 复合类型,如 StructsMessages 也必须大写。

Instantiation

您可以创建以下类型的实例:

struct StExample {
fieldInitInt = 1;
fieldUninitInt;
}
fun example() {
// 带有 fieldInit 默认值的实例
StExample{ fieldUninit: 2 };
// 带有两个字段设置的实例
StExample{
fieldInit0,
fieldUninit: 2, // 允许使用尾部逗号
};
}

Field access

您可以直接访问以下类型的字段:

struct StExample {
fieldInitInt = 1;
fieldUninitInt;
}
fun example():Int {
let structStExample = StExample{ fieldUninit: 2 }; // 实例化
struct.fieldInit; // 访问字段
return struct.fieldUninit; // 从函数中返回字段值
}

Extension function call

扩展函数仅在特定类型中定义。 它们的调用方式类似于许多其他语言中的方法调用:

42.toString(); // toString() 是针对 Int 类型定义的 stdlib 函数。

Static function call

在函数体的任何位置,都可以调用全局 static functioncontract 的内部函数:

contract ExampleContract {
receive() {
now(); // now() 是 stdlib 的静态函数
let expirationInt = now() + 1000; // 运算和变量声明
expiration = self.answerQuestion(); // 内部函数
}
fun answerQuestion():Int {
return 42;
}
}

initOf

表达式 initOf 计算 contract 的初始状态 (StateInit):

// 合同的 init() 函数的参数值
// ↓ ↓
initOf ExampleContract(42, 100); // 返回一个 Struct StateInit{}
// ---------------
// ↑
// 合同名称
// ↓
// ---------------
initOf ExampleContract(
42, // 第一个参数
100, // 第二个参数,允许使用逗号
);

其中,StateInit是一个内置结构,由以下部分组成:

现场类型说明
代码[单元格][单元格]合同的初始代码(编译后的字节码
数据[单元格][单元格]合同的初始数据(合同的 init()函数参数