运算符
几乎所有合约都对数据进行操作:将某些值转换成另一个值。 范围可能各不相同,但运营商是此类修改的核心。 范围可能会有所不同,但运算符是此类修改的核心。
本页按照优先级 的递减顺序列出了 Tact 中的所有运算符,并附有使用示例。
运算符列表
下表列出了按 优先级:从高到低递减的运算符。
简要说明 | 运算符 |
---|---|
括号 | () |
一元后缀 | !! |
一元前缀 | + - ! ~ |
乘法 | * / % |
加法 | + - |
移位 | >> << |
关系运算符 | > >= < <= |
等式 | == != |
按位与(Bitwise AND) | & |
按位异或(Bitwise XOR) | ^ |
按位或(Bitwise OR) | | |
逻辑与(Logical AND) | && |
逻辑或(Logical OR) | || |
三元 | ?: |
赋值 | = 和 所有增强赋值运算符 |
优先级
本页所有运算符的优先级从高到低依次递减。 优先级用于选择在特定情况下考虑哪个运算符。 每当出现模棱两可的情况时,Tact 会优先选择优先级较高的运算符,而不是优先级较低的运算符。
例如,减号 (-
) 可被视为减法运算符或否定运算符,它将表达式的正负符号颠倒过来,反之亦然。 由于在两者有歧义的情况下,后者的优先级高于前者,Tact 将首先把 -
视为否定操作符。 如果这对给定表达式没有意义,它才会将其视为减法运算符。
请看下面的代码
尽管这个例子可能很简单,但忽略优先级规则往往会导致运算符出现混乱的情况。 由于括号在所有表达式和运算符中具有最高优先级,因此用括号封装每个操作可以确保正确的操作顺序。
括号,()
括号(也可称为圆括号,()
)与其说是实际的运算符,不如说是一种标点符号,但其 优先级 高于任何其他运算符的优先级。 使用括号可覆盖运算顺序:
一元
这里的 “一元 “是指只应用于给定表达式的一个操作数。 除了非空断言,所有一元运算符都具有相同的优先级。
一元运算符可以是两种类型之一:
- 前缀(Prefix) - 放在表达式之前。
- 后缀(Postfix 或 suffix) - 放在表达式之后。
非空断言,!!
一元双叹号(非空断言)运算符 !
是一个后缀运算符,它强制执行非null
值,如果可选变量不是null
,则允许直接访问可选变量的值。 否则,如果编译器可以跟踪,则引发编译错误;如果不能跟踪,则抛出退出码 128异常:空引用异常”。 可以适用于任何可选变量,无论其非null
类型如何。
加号,+
虽然 Tact 编译器的语法中指定了一元加号运算符 +
,但它只作为 二元运算符 存在。
否定,-
一元减号(negation)运算符 -
是一个前缀运算符,用于反转表达式的符号。 只能应用于 Int
类型的值:
反转,!
一元感叹号(inversion)运算符 !
是一个前缀运算符,用于反转表达式的布尔值——将 true
变为 false
,反之亦然。只 只能应用于 Bool
类型的值:
按位非,~
单引号 tilde(bitwise not)运算符 ~
是一个前缀运算符,它将表达式二进制表示中的每一位反转或_flip_,即把 改为 ,反之亦然。 只能应用于 Int
类型的值:
二进制
二进制运算符按优先级递减的顺序分成几个小节。 每个小节中的操作符与小节本身具有相同的 优先级。
乘法
乘、除或求余数。
乘法,*
二进制星号 (multiplication) 运算符 *
用于两个值的乘法运算。 可能导致 整数溢出。
只能应用于 Int
类型的值:
除法,/
二进制斜线 (division) 运算符 /
用于两个值的整除,如果结果为正,则向零截断,如果结果为负,则从零截断。这也叫向下舍入(或向 舍入)。 这也叫 向下舍入(或向 舍入)。
如果尝试除以零,则会出现退出码 4错误:整数溢出。
只能应用于 Int
类型的值:
取模, %
二进制百分号 (modulo) 运算符 %
用于获取整数除法的模数,不能与获取余数混淆。 对于符号相同的两个值,模运算和余运算是等价的,但当操作数的符号不同时,模运算的结果总是与 除数(右边的值)的符号相同,而余运算的结果与 除数(左边的值)的符号相同,这可能使它们相差一个单位的 除数。
只能应用于 Int
类型的值:
避免两者混淆的最简单方法是通过 abs(x: Int)
优先使用正值:
加法
加法或减法。
添加,+
二进制加法运算符 +
用于将数字相加。 超出 Int
的最大值将导致退出码 4错误:整数溢出”。
只能应用于 Int
类型的值:
减法,-
二进制减号(subtraction)运算符 -
用于将数字相减。 二进制减号(subtraction)运算符 -
用于将数字相减。 超出 Int
的最小值将导致退出码 4错误:整数溢出。
只能应用于 Int
类型的值:
按位移位
向左或向右移动位。
右移,>>
二进制 double greater than(比特向右移动)运算符 >>
返回一个整数,其二进制表示为 左操作数 的值向右移动了 右操作数 的位数。 向右移位的多余位被丢弃,最左边位的副本从左边移入。 这种操作也称为 “符号向右移动 “或 “算术向右移动”,因为结果数字的符号与左操作数的符号相同。 这是一种更有效的方法,即用 除以 左操作数 ,其中 等于 右操作数。
只能应用于 Int
类型的值:
左移,<<
二进制双大于号(bitwise shift left)运算符 <<
返回一个整数,其二进制表示为左操作数的值向左移动右操作数的位数。 向左移位的多余比特被丢弃,零比特从右边移入。 这是一种更有效的方法,可以将 左操作数 乘以 ,其中 等于 右操作数。 超出 Int
的最大值将导致退出码 4 错误:整数溢出。
只能应用于 Int
类型的值:
关系
查找更大、更小或相等的数值。
大于,>
二进制 大于 运算符 >
如果左操作数大于右操作数,则返回 true
,否则返回 false
。 只能应用于 Int
类型的值:
大于或等于,>=
二进制 大于或等于 运算符 >=
如果左操作数大于或等于右操作数,则返回 true
,否则返回 false
。 只能应用于 Int
类型的值:
小于,<
二进制 小于 运算符 <
如果左操作数小于右操作数,则返回 true
,否则返回 false
。 只能应用于 Int
类型的值:
小于或等于,<=
二进制 小于或等于 运算符 <=
如果左操作数小于或等于右操作数,则返回 true
,否则返回 false
。 只能应用于 Int
类型的值:
等于与不等于,==
!=
二进制相等(equal)运算符 ==
检查其两个操作数是否_equal_,返回结果类型 Bool
。
二进制不等(not equal)运算符 !=
检查其两个操作数是否_not equal_,返回一个 Bool
类型的结果。
除了 Cell
和 Slice
类型会通过哈希值进行隐式比较外,这两种操作符都要求操作数为相同类型,并且都不执行隐式类型转换。
这两种运算符都可以应用于下列类型和值:
Int
Bool
Address
cell
,通过.hash()
隐式比较Slice
,通过.hash()
隐式比较String
map<K, V>
,但前提是它们的键和值类型相同- Optionals and
null
value
按位与,&
二进制与(按位与)运算符 &
执行按位与操作,该操作对操作数中每一对对应的位执行逻辑与运算。 二进制安培(比特 AND)运算符 &
应用比特 AND,对操作数的每一对相应比特执行逻辑 AND运算。 当我们要清除一个数字的选定位时,这一点非常有用,因为每个位都代表一个单独的标志或布尔状态,这使得每个整数可以 “存储 “多达 个布尔值,因为 Tact 中的所有整数都是 - 位有符号的。
只能应用于 Int
类型的值:
按位异或,^
二进制插入符号(按位异或)运算符 ^
执行按位异或操作,该操作对操作数中每一对对应的位执行逻辑异或运算。 如果只有一个位是 ,则每个位置的结果都是 ,但如果两个位都是 或两个位都是 ,则结果都是 。 在此,它对两个bit进行比较,如果两个bit不同则给出,如果相同则给出。
这对于反转操作数的选定位(也称为切换或翻转)很有用,因为任何位都可以通过与 进行”异或”来切换。
只能应用于 Int
类型的值:
按位或,|
二进制竖线(按位或)运算符 |
执行按位或操作,该操作对操作数中每一对对应的位执行逻辑或运算。 当我们要应用特定的 bitmask 时,这很有用。
例如,按位或 通常用于 Tact 中通过掩码特定位为 来结合基本模式和可选标志,以构造目标消息模式。
只能应用于 Int
类型的值:
逻辑与, &&
二进制逻辑 AND(逻辑连接)运算符 &&
如果两个操作数都是 true
,则返回 true
,否则返回 false
。 它是短路的,也就是说,如果左操作数是 false
,它会立即将整个表达式求值为 false
,而不求值右操作数。 这是短路的,意味着如果左操作数为false
,它将立即将整个表达式评估为false
,而不会评估右操作数。
只能应用于 Bool
类型的值:
逻辑或,||
二进制逻辑或(逻辑或)运算符 ||
仅当两个操作数都为 false
时返回 false
,否则返回 true
。 它是短路的,也就是说,如果左操作数是 true
,它会立即将整个表达式评估为 true
,而不评估右操作数。
只能应用于 Bool
类型的值:
三元,?:
条件(ternary)运算符是唯一一个包含三个操作数的 Tact 运算符:一个条件,后面跟一个问号(?
),然后是如果条件被评估为true
时要执行的表达式,后面跟一个冒号(:
),最后是如果条件被评估为false
时要执行的表达式。 该运算符常用于替代 if...else
语句。
条件必须解析为类型Bool
:
三元运算符是除 赋值相关运算符 外唯一具有右关联性的运算符。 这意味着,在模棱两可的情况下,Tact 会优先选择最长的匹配序列。 简而言之,这使得三元运算符的无括号嵌套成为可能,但仅限于替代情况(冒号 :
后面的部分):
赋值,=
赋值操作符 =
用于为变量或 Message 或 Struct 的属性赋值。 赋值是一个语句,不返回值。
增强赋值
增强(或复合)赋值运算符,如 +=
,将操作与 赋值 结合起来。 增强赋值是一个语句,不返回值。
增强赋值在语义上等价于常规赋值,但附带一个操作:
增强赋值运算符列表:
+=
,使用 加法运算符+
。 只能应用于Int
类型的值。-=
,使用 减法运算符-
。 只能应用于Int
类型的值。*=
,使用 乘法运算符*
。 只能应用于Int
类型的值。/=
,使用 除法运算符/
。 只能应用于Int
类型的值。%=
,使用 modulo 运算符%
。 只能应用于Int
类型的值。&=
,使用 bitwise AND 运算符&
。 只能应用于Int
类型的值。^=
,它使用 bitwise XOR 运算符^
。 只能应用于Int
类型的值。|=
,它使用 bitwise OR 运算符|
。 只能应用于Int
类型的值。