---
title: 运算符
description: 本页按照[优先级](#precedence)的递减顺序列出了 Tact 中的所有运算符，并附有使用示例
prev:
  link: /zh-cn/book/exit-codes
  label: 退出码
---

几乎所有合约都对数据进行操作：将某些值转换成另一个值。 范围可能各不相同，但运营商是此类修改的核心。 范围可能会有所不同，但运算符是此类修改的核心。

本页按照[优先级](#precedence) 的递减顺序列出了 Tact 中的所有运算符，并附有使用示例。

:::note

  需要注意的是，Tact 中没有隐式类型转换，因此运算符不能用来添加不同类型的值，或者在不明确转换为相同类型的情况下比较它们的相等性。 这是通过标准库中的某些函数实现的。 需要注意的是，Tact 中没有隐式类型转换，因此运算符不能用来添加不同类型的值，或者在不明确转换为相同类型的情况下比较它们的相等性。 这是通过标准库中的某些函数实现的。 请参阅 [`Int.toString(){:tact}`](/zh-cn/ref/core-strings#inttostring)，了解此类函数的示例。

:::

## 运算符列表 {#table}

下表列出了按 [优先级](#precedence)：从高到低递减的运算符。

| 简要说明              | 运算符
| :-------------------- | :-----
| 括号                  | [`(){:tact}`][paren]
| 一元后缀              | [`!!{:tact}`][nna]
| 一元前缀              | [`+{:tact}`][plus] &nbsp; [`-{:tact}`][neg] &nbsp; [`!{:tact}`][inv] &nbsp; [`~{:tact}`][b-not]
| 乘法                  | [`*{:tact}`][mul] &nbsp; [`/{:tact}`][div] &nbsp; [`%{:tact}`][mod]
| 加法                  | [`+{:tact}`][add] &nbsp; [`-{:tact}`][sub]
| 移位                  | [`>>{:tact}`][shr] &nbsp; [`<<{:tact}`][shl]
| 关系运算符            | [`>{:tact}`][gt] &nbsp; [`>={:tact}`][ge] &nbsp; [`<{:tact}`][lt] &nbsp; [`<={:tact}`][le]
| 等式                  | [`=={:tact}`][eq] &nbsp; [`!={:tact}`][eq]
| 按位与(Bitwise AND)   | [`&{:tact}`][b-and]
| 按位异或(Bitwise XOR) | [`^{:tact}`][b-xor]
| 按位或(Bitwise OR)    | [`\|{:tact}`][b-or]
| 逻辑与(Logical AND)   | [`&&{:tact}`][l-and]
| 逻辑或(Logical OR)    | [`\|\|{:tact}`][l-or]
| 三元                  | [`?:{:tact}`][ternary]
| 赋值                  | [`={:tact}`][assign] 和 [所有增强赋值运算符](#augmented-assignment)

[paren]: #parentheses
[nna]: #unary-non-null-assert
[plus]: #unary-plus
[neg]: #unary-negate
[inv]: #unary-inverse
[b-not]: #unary-bitwise-not
[mul]: #binary-multiply
[div]: #binary-divide
[mod]: #binary-modulo
[add]: #binary-add
[sub]: #binary-subtract
[shr]: #binary-bitwise-shift-right
[shl]: #binary-bitwise-shift-left
[gt]: #binary-greater
[ge]: #binary-greater-equal
[lt]: #binary-less
[le]: #binary-less-equal
[eq]: #binary-equality
[b-and]: #binary-bitwise-and
[b-xor]: #binary-bitwise-xor
[b-or]: #binary-bitwise-or
[l-and]: #binary-logical-and
[l-or]: #binary-logical-or
[ternary]: #ternary
[assign]: #assignment

## 优先级 {#precedence}

本页所有运算符的优先级从高到低依次递减。 优先级用于选择在特定情况下考虑哪个运算符。 每当出现模棱两可的情况时，Tact 会优先选择优先级较高的运算符，而不是优先级较低的运算符。

例如，减号 (`-{:tact}`) 可被视为减法运算符或否定运算符，它将表达式的正负符号颠倒过来，反之亦然。  由于在两者有歧义的情况下，后者的优先级高于前者，Tact 将首先把 `-{:tact}` 视为否定操作符。 如果这对给定表达式没有意义，它才会将其视为减法运算符。

请看下面的代码

```tact
5 + -5; // 在这里，减号将被视为否定运算符
5 -5; // 而在这里，尽管有格式限制，它仍将被视为减法运算符
```

尽管这个例子可能很简单，但忽略优先级规则往往会导致运算符出现混乱的情况。 由于括号在所有表达式和运算符中具有最高优先级，因此用[括号](#parentheses)封装每个操作可以确保正确的操作顺序。

## 括号，`()` {#parentheses}

括号（也可称为圆括号，`(){:tact}`）与其说是实际的运算符，不如说是一种标点符号，但其 [优先级](#precedence) 高于任何其他运算符的优先级。 使用括号可覆盖运算顺序：

```tact
5 * 5 - 2;   // 23
5 * (5 - 2); // 15
```

:::note

  当前允许的最大嵌套级别是 $83$。 试图写入更深的表达式会导致编译错误：

```tact
fun elegantWeaponsForCivilizedAge(): Int {
    return
    ((((((((((((((((((((((((((((((((
        ((((((((((((((((((((((((((((((((
            (((((((((((((((((((( // 84 parens, compilation error!
                42
            ))))))))))))))))))))
        ))))))))))))))))))))))))))))))))
    ))))))))))))))))))))))))))))))));
}
```

:::

## 一元

这里的 "一元 "是指只应用于给定表达式的一个操作数。 除了[非空断言](#unary-non-null-assert)，所有一元运算符都具有相同的[优先级](#precedence)。

一元运算符可以是两种类型之一：

- 前缀(Prefix) - 放在表达式之前。
- 后缀(Postfix 或 suffix) - 放在表达式之后。

### 非空断言，`!!` {#unary-non-null-assert}

一元双叹号（_非空断言_）运算符 `!{:tact}`是一个后缀运算符，它强制执行非`null{:tact}`值，如果可选变量不是`null{:tact}`，则允许直接访问可选变量的值。  否则，如果编译器可以跟踪，则引发编译错误；如果不能跟踪，则抛出[退出码 128](/zh-cn/book/exit-codes#128)异常：空引用异常"。 可以适用于任何可选变量，无论其非`null{:tact}`类型如何。

:::note

  点击此处了解更多有关可选变量和字段的信息：[可选变量](/zh-cn/book/optionals)

:::

### 加号，`+` {#unary-plus}

虽然 Tact 编译器的语法中指定了一元加号运算符 `+{:tact}`，但它只作为 [二元运算符](#binary-add) 存在。

### 否定，`-` {#unary-negate}

一元减号（_negation_）运算符 `-{:tact}` 是一个前缀运算符，用于反转表达式的符号。  只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let five: Int = 5;
five + -five; // here, the minus sign is a negation operator, not a subtraction operator
-(-1);        // double application gives back the original value, which is 1
--1;          // 1
```

### 反转，`!` {#unary-inverse}

一元感叹号（_inversion_）运算符 `!{:tact}` 是一个前缀运算符，用于反转表达式的布尔值——将 `true{:tact}` 变为 `false{:tact}`，反之亦然。只 只能应用于 [`Bool{:tact}`][bool]类型的值：

```tact
let iLikeTact: Bool = true;
!iLikeTact; // false
!false;     // true
!(!false);  // false
!!false;    // false
```

### 按位非，`~` {#unary-bitwise-not}

单引号 tilde（_bitwise not_）运算符 `~{:tact}` 是一个前缀运算符，它将表达式二进制表示中的每一位反转或_flip_，即把 $1$ 改为 $0$，反之亦然。  只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let answer: Int = 42;
~answer;    // -43
~(~answer); // 42
~(~0);      // 0
~~0;        // 0
```

## 二进制

二进制运算符按[优先级](#precedence)递减的顺序分成几个小节。 每个小节中的操作符与小节本身具有相同的 [优先级](#precedence)。

### 乘法 {#binary-multiplication}

乘、除或求余数。

#### 乘法，`*` {#binary-multiply}

二进制星号 (_multiplication_) 运算符 `*{:tact}` 用于两个值的乘法运算。  可能导致 [整数溢出](/zh-cn/book/integers#operations)。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two * two;         // 4
0 * 1_000_000_000; // 0
-1 * 5;            // -5

pow(2, 255) * pow(2, 255); // build error: integer overflow!
```

#### 除法，`/` {#binary-divide}

二进制斜线 (_division_) 运算符 `/{:tact}` 用于两个值的整除，如果结果为正，则向零截断，如果结果为负，则从零截断。这也叫[向下舍入](https://en.wikipedia.org/wiki/Rounding#Rounding_down)（或向 $-\infty$ 舍入）。 这也叫 [向下舍入](https://en.wikipedia.org/wiki/Rounding#Rounding_down)（或向 $-∞$ 舍入）。

如果尝试除以零，则会出现[退出码 4](/zh-cn/book/exit-codes#4)错误：整数溢出。

只能应用于 [`Int{:tact}`][int] 类型的值：

```tact
let two: Int = 2;
two / 2; // 1
two / 1; // 2
-1 / 5;  // -1
-1 / -5; // 0
1 / -5;  // -1
1 / 5;   // 0
6 / 5;   // 1, rounding down
-6 / 5;  // -2, rounding down (towards -∞)
```

:::note

  请注意，对于 `Int{:tact}` 类型，除法运算符和模数运算符之间的以下关系始终成立：

```tact
a / b * b + a % b == a; // true for any Int values of `a` and `b`,
                        //   except when `b` is equal to 0 and we divide `a` by 0,
                        //   which is an attempt to divide by zero resulting in an error
```

:::

#### 取模, `%` {#binary-modulo}

二进制百分号 (_modulo_) 运算符 `%{:tact}` 用于获取整数除法的模数，不能与获取余数混淆。  对于符号相同的两个值，模运算和余运算是等价的，但当操作数的符号不同时，模运算的结果总是与 _除数_（右边的值）的符号相同，而余运算的结果与 _除数_（左边的值）的符号相同，这可能使它们相差一个单位的 _除数_。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two % 2; // 0
two % 1; // 1

1 % 5;   // 1
-1 % 5;  // 4
1 % -5;  // -4
-1 % -5; // -1
```

避免两者混淆的最简单方法是通过 [`abs(x: Int){:tact}`](/zh-cn/ref/core-math#abs)优先使用正值：

```tact
abs(-1) % abs(-5); // 1
```

:::note

  你知道吗，在JavaScript中`%{:tact}`作为_余数_运算符使用，而不是像Tact中那样的_模_运算符（像在Tact中那样）？\
  [余数 (%) - JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder#description)\
  [模 - 维基百科](https://en.wikipedia.org/wiki/Modulo)

:::

### 加法 {#binary-addition}

加法或减法。

#### 添加，`+` {#binary-add}

二进制加法运算符 `+{:tact}` 用于将数字相加。 超出 [`Int{:tact}`][int]的最大值将导致[退出码 4](/zh-cn/book/exit-codes#4)错误：整数溢出"。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two + 2; // 4
-1 + 1;  // 0

pow(2, 254) + pow(2, 254);     // 2 * 2^254
pow(2, 255) + pow(2, 255);     // build error: integer overflow!
pow(2, 255) - 1 + pow(2, 255); // 2^256 - 1, maximal value of any integer in Tact!
```

#### 减法，`-` {#binary-subtract}

二进制减号（_subtraction_）运算符 `-{:tact}` 用于将数字相减。 二进制减号（_subtraction_）运算符 `-{:tact}` 用于将数字相减。 超出 [`Int{:tact}`][int]的最小值将导致[退出码 4](/zh-cn/book/exit-codes#4)错误：整数溢出。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two - 2; // 0
-1 - 1;  // -2

pow(2, 254) - pow(2, 254); // 0
pow(2, 255) - pow(2, 255); // 0
pow(2, 256) - pow(2, 256); // build error: integer overflow!
```

### 按位移位 {#binary-bitwise-shifts}

向左或向右移动位。

#### 右移，`>>` {#binary-bitwise-shift-right}

二进制 double greater than（_比特向右移动_）运算符 `>>{:tact}` 返回一个整数，其二进制表示为 _左操作数_ 的值向右移动了 _右操作数_ 的位数。 向右移位的多余位被丢弃，最左边位的副本从左边移入。 这种操作也称为 "符号向右移动 "或 "算术向右移动"，因为结果数字的符号与左操作数的符号相同。 这是一种更有效的方法，即用 $2^n$ 除以 _左操作数_ ，其中 $n$ 等于 _右操作数_。

只能应用于 [`Int{:tact}`][int] 类型的值：

```tact
let two: Int = 2;
two >> 1; // 1
4 >> 1;   // 2
5 >> 1;   // 2, due to flooring of integer values

pow(2, 254) >> 254; // 1
```

:::note

  [Bit shifts - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

#### 左移，`<<` {#binary-bitwise-shift-left}

二进制双大于号（_bitwise shift left_）运算符 `<<{:tact}` 返回一个整数，其二进制表示为左操作数的值向左移动右操作数的位数。 向左移位的多余比特被丢弃，零比特从右边移入。 这是一种更有效的方法，可以将 _左操作数_ 乘以 $2^n$，其中 $n$ 等于 _右操作数_。 超出 [`Int{:tact}`][int] 的最大值将导致[退出码 4](/zh-cn/book/exit-codes#4) 错误：整数溢出。

只能应用于 [`Int{:tact}`][int] 类型的值：

```tact
let two: Int = 2;
two << 1; // 4
1 << 5;   // 1 * 2^5, which is 32
2 << 5;   // 2 * 2^5, which is 64

pow(2, 254) == (1 << 254); // true
pow(2, 254) == 1 << 254; // true, no parentheses needed due to higher precedence of >> over ==
pow(2, 255) == 1 << 255; // true, but we're very close to overflow here!
```

:::note

  [Bit shifts - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### 关系 {#binary-relation}

查找更大、更小或相等的数值。

#### 大于，`>` {#binary-greater}

二进制 _大于_ 运算符 `>{:tact}` 如果左操作数大于右操作数，则返回 `true{:tact}`，否则返回 `false{:tact}`。 只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two > 2; // false
-1 > -3; // true
```

#### 大于或等于，`>=` {#binary-greater-equal}

二进制 _大于或等于_ 运算符 `>={:tact}` 如果左操作数大于或等于右操作数，则返回 `true{:tact}`，否则返回 `false{:tact}`。  只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two >= 2; // true
-1 >= -3; // true
```

#### 小于，`<` {#binary-less}

二进制 _小于_ 运算符 `<{:tact}` 如果左操作数小于右操作数，则返回 `true{:tact}`，否则返回 `false{:tact}`。  只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two < 2; // false
-1 < -3; // false
```

#### 小于或等于，`<=` {#binary-less-equal}

二进制 _小于或等于_ 运算符 `<={:tact}` 如果左操作数小于或等于右操作数，则返回 `true{:tact}`，否则返回 `false{:tact}`。  只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two <= 2; // true
-1 <= -3; // false
```

### 等于与不等于，`==` `!=` {#binary-equality}

二进制相等（_equal_）运算符 `=={:tact}` 检查其两个操作数是否_equal_，返回结果类型 [`Bool{:tact}`][bool]。

二进制不等（_not equal_）运算符 `!={:tact}` 检查其两个操作数是否_not equal_，返回一个 [`Bool{:tact}`][bool] 类型的结果。

除了 [`Cell{:tact}`][cell]和 [`Slice{:tact}`][slice]类型会通过哈希值进行隐式比较外，这两种操作符都要求操作数为相同类型，并且都不执行隐式类型转换。

这两种运算符都可以应用于下列类型和值：

- [`Int{:tact}`][int]
- [`Bool{:tact}`][bool]
- [`Address{:tact}`][p]
- [`cell{:tact}`][cell]，通过`.hash(){:tact}`隐式比较
- [`Slice{:tact}`][slice]，通过`.hash(){:tact}`隐式比较
- [`String{:tact}`][p]
- [`map<K, V>{:tact}`](/zh-cn/book/maps)，但前提是它们的键和值类型相同
- [Optionals and `null{:tact}` value](/zh-cn/book/optionals)

```tact
// Int:
2 == 3; // false
2 != 3; // true

// Bool:
true == true;  // true
false != true; // true

// Address:
myAddress() == myAddress(); // true
myAddress() != myAddress(); // false

// Cell:
emptyCell() == emptyCell(); // true
emptyCell() != emptyCell(); // false

// Slice:
"A".asSlice() == "A".asSlice(); // true
"A".asSlice() != "A".asSlice(); // false

// String:
"A" == "A"; // true
"A" != "A"; // false

// map<K, V>:
let map1: map<Int, Int> = emptyMap();
let map2: map<Int, Int> = emptyMap();
map1 == map2; // true
map1 != map2; // false

// Optionals and null values themselves
let nullable: Int? = null;
nullable == null; // true
null == null;     // true
nullable != null; // false
null != null;     // false

let anotherNullable: Int? = 5;
nullable == anotherNullable; // false
nullable != anotherNullable; // true
```

:::note

  二进制相等 `=={:tact}` 和不等式 `!={:tact}` 运算符通过[`.hash(){:tact}`](/zh-cn/ref/core-cells#cellhash)函数，隐式地通过各自[cell][cell]的哈希值比较[maps](/zh-cn/book/maps)。 虽然这在大多数情况下没有问题，因为大多数映射序列化器的工作原理与 TON 区块链源中的序列化器相同，但通过手动序列化映射或更改某些库中序列化器的逻辑，仍有可能得到错误的负面结果。

  如果你需要保证比较的映射是相等的，并且愿意为此支付更多的gas，可以使用 [`map.deepEquals(){:tact}`](/zh-cn/book/maps#deepequals) 函数。

:::

### 按位与，`&` {#binary-bitwise-and}

二进制与（_按位与_）运算符 `&{:tact}` 执行[按位与](https://en.wikipedia.org/wiki/Bitwise_operation#AND)操作，该操作对操作数中每一对对应的位执行[逻辑与](#binary-logical-and)运算。 二进制安培（_比特 AND_）运算符 `&{:tact}` 应用[比特 AND](https://en.wikipedia.org/wiki/Bitwise_operation#AND)，对操作数的每一对相应比特执行[逻辑 AND](#binary-bitwise-and)运算。 当我们要清除一个数字的选定位时，这一点非常有用，因为每个位都代表一个单独的标志或布尔状态，这使得每个整数可以 "存储 "多达 $257$ 个布尔值，因为 Tact 中的所有整数都是 $257$- 位有符号的。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two & 1; // 0
4 & 1;   // 0
3 & 1;   // 1
1 & 1;   // 1

255 & 0b00001111;        // 15
0b11111111 & 0b00001111; // 15
```

:::note

  [Bitwise AND - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#AND)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### 按位异或，`^` {#binary-bitwise-xor}

二进制插入符号（_按位异或_）运算符 `^{:tact}` 执行[按位异或](https://en.wikipedia.org/wiki/Bitwise_operation#XOR)操作，该操作对操作数中每一对对应的位执行[逻辑异或](https://en.wikipedia.org/wiki/Exclusive_or)运算。 如果只有一个位是 $1$，则每个位置的结果都是 $1$ ，但如果两个位都是 $0$ 或两个位都是 $1$，则结果都是 $0$。 在此，它对两个bit进行比较，如果两个bit不同则给出$1$，如果相同则给出$0$。

这对于反转操作数的选定位（也称为切换或翻转）很有用，因为任何位都可以通过与 $1$ 进行"异或"来切换。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two ^ 3; // 1
4 ^ 1;   // 0
3 ^ 1;   // 3
1 ^ 1;   // 0

255 ^ 0b00001111;        // 240
0b11111111 ^ 0b00001111; // 240
```

:::note

  [Bitwise XOR - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#XOR)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### 按位或，`|` {#binary-bitwise-or}

二进制竖线（_按位或_）运算符 `|{:tact}` 执行[按位或](https://en.wikipedia.org/wiki/Bitwise_operation#OR)操作，该操作对操作数中每一对对应的位执行[逻辑或](#binary-logical-or)运算。 当我们要应用特定的 [bitmask](https://en.wikipedia.org/wiki/Mask_(computing)) 时，这很有用。

例如，_按位或_ 通常用于 Tact 中通过掩码特定位为 $1$ 来[结合基本模式和可选标志](/zh-cn/book/message-mode#combining-modes-with-flags)，以构造目标[消息模式](/zh-cn/book/message-mode)。

只能应用于 [`Int{:tact}`][int]类型的值：

```tact
let two: Int = 2;
two | 1; // 3
4 | 1;   // 5
3 | 1;   // 3
1 | 1;   // 1

255 | 0b00001111;        // 255
0b11111111 | 0b00001111; // 255
```

:::note

  [Bitwise OR - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#OR)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### 逻辑与, `&&` {#binary-logical-and}

二进制逻辑 AND（[逻辑连接](https://en.wikipedia.org/wiki/Logical_conjunction)）运算符 `&&{:tact}` 如果两个操作数都是 `true{:tact}`，则返回 `true{:tact}`，否则返回 `false{:tact}`。 它是短路的，也就是说，如果左操作数是 `false{:tact}`，它会立即将整个表达式求值为 `false{:tact}`，而不求值右操作数。 这是短路的，意味着如果左操作数为`false{:tact}`，它将立即将整个表达式评估为`false{:tact}`，而不会评估右操作数。

只能应用于 [`Bool{:tact}`][bool]类型的值：

```tact
let iLikeTact: Bool = true;
iLikeTact && true;  // true, evaluated both operands
iLikeTact && false; // false, evaluated both operands
false && iLikeTact; // false, didn't evaluate iLikeTact
```

### 逻辑或，`||` {#binary-logical-or}

二进制逻辑或（[逻辑或](https://en.wikipedia.org/wiki/Logical_disjunction)）运算符 `||{:tact}` 仅当两个操作数都为 `false{:tact}` 时返回 `false{:tact}`，否则返回 `true{:tact}`。 它是短路的，也就是说，如果左操作数是 `true{:tact}`，它会立即将整个表达式评估为 `true{:tact}`，而不评估右操作数。

只能应用于 [`Bool{:tact}`][bool]类型的值：

```tact
let iLikeSnails: Bool = false;
iLikeSnails || true;  // true, evaluated both operands
iLikeSnails || false; // false, evaluated both operands
true || iLikeSnails;  // true, didn't evaluate iLikeSnails
```

## 三元，`?:` {#ternary}

条件（_ternary_）运算符是唯一一个包含三个操作数的 Tact 运算符：一个条件，后面跟一个问号（`?{:tact}`），然后是如果条件被评估为`true{:tact}`时要执行的表达式，后面跟一个冒号（`:{:tact}`），最后是如果条件被评估为`false{:tact}`时要执行的表达式。  该运算符常用于替代 [`if...else{:tact}`](/zh-cn/book/statements#if-else) 语句。

条件必须解析为类型[`Bool{:tact}`][bool]:

```tact
// condition
// ↓
true ? "incredibly so" : "absolutely not"; // "incredibly so"
//     ---------------   ----------------
//     ↑                 ↑
//     |                 alternative, when condition is false
//     |
//     consequence, when condition is true

2 + 2 == 4 ? true : false; // true
```

三元运算符是除 [赋值相关运算符](#assignment) 外唯一具有右关联性的运算符。 这意味着，在模棱两可的情况下，Tact 会优先选择最长的匹配序列。 简而言之，这使得三元运算符的无括号嵌套成为可能，但仅限于替代情况（冒号 `:{:tact}` 后面的部分）：

```tact
// don't need additional parentheses for alternative cases
false ? 1 : (false ? 2 : 3); // 3
false ? 1 : false ? 2 : 3;   // also 3
false ? 1 : true ? 2 : 3;    // 2

// need additional parentheses for consequence cases (parts in-between ? and :)
false ? (false ? 1 : 2) : 3; // 3
false ? false ? 1 : 2 : 3;   // SYNTAX ERROR!
true  ? (false ? 1 : 2) : 3; // 2
```

## 赋值，`=` {#assignment}

赋值操作符 `={:tact}` 用于为变量或 [Message](/zh-cn/book/structs-and-messages#messages) 或 [Struct](/zh-cn/book/structs-and-messages#structs) 的属性赋值。  赋值是一个语句，不返回值。

```tact
let someVar: Int = 5;    // assignment operator = is used here...
someVar = 4;             // ...and here
someVar = (someVar = 5); // SYNTAX ERROR!
```

### 增强赋值 {#augmented-assignment}

增强（或复合）赋值运算符，如 `+={:tact}`，将操作与 [赋值](#assignment) 结合起来。  增强赋值是一个语句，不返回值。

增强赋值在语义上等价于常规赋值，但附带一个操作：

```tact
let value: Int = 5;

// this:
value += 5;
// is equivalent to this:
value = value + 5;
```

增强赋值运算符列表：

- `+={:tact}`，使用 [加法运算符 `+{:tact}`](#binary-add)。  只能应用于 [`Int{:tact}`][int]类型的值。
- `-={:tact}`，使用 [减法运算符 `-{:tact}`](#binary-subtract)。  只能应用于 [`Int{:tact}`][int]类型的值。
- `*={:tact}`，使用 [乘法运算符 `*{:tact}`](#binary-multiply)。  只能应用于 [`Int{:tact}`][int]类型的值。
- `/={:tact}`，使用 [除法运算符 `/{:tact}`](#binary-divide)。  只能应用于 [`Int{:tact}`][int]类型的值。
- `%={:tact}`，使用 [modulo 运算符 `%{:tact}`](#binary-modulo)。  只能应用于 [`Int{:tact}`][int]类型的值。
- `&={:tact}`，使用 [bitwise AND 运算符 `&{:tact}`](#binary-bitwise-and)。 只能应用于 [`Int{:tact}`][int]类型的值。
- `^={:tact}`，它使用 [bitwise XOR 运算符 `^{:tact}`](#binary-bitwise-xor)。  只能应用于 [`Int{:tact}`][int]类型的值。
- `|={:tact}`，它使用 [bitwise OR 运算符 `|{:tact}`](#binary-bitwise-or)。 只能应用于 [`Int{:tact}`][int]类型的值。

```tact
let value: Int = 5;

// +=
value + 5;         // adds 5
value = value + 5; // adds 5 and assigns result back
value += 5;        // also adds 5 and assigns result back

// -=
value - 5;         // subtracts 5
value = value - 5; // subtracts 5 and assigns result back
value -= 5;        // also subtracts 5 and assigns result back

// *=
value * 5;         // multiplies by 5
value = value * 5; // multiplies by 5 and assigns result back
value *= 5;        // also multiplies by 5 and assigns result back

// /=
value / 5;         // divides by 5
value = value / 5; // divides by 5 and assigns result back
value /= 5;        // also divides by 5 and assigns result back

// %=
value % 5;         // gets modulo by 5
value = value % 5; // gets modulo by 5 and assigns result back
value %= 5;        // also gets modulo by 5 and assigns result back

// &=
value & 5;         // bitwise ANDs 5
value = value & 5; // bitwise ANDs 5 and assigns result back
value &= 5;        // also bitwise ANDs 5 and assigns result back

// ^=
value ^ 5;         // bitwise XORs 5
value = value ^ 5; // bitwise XORs 5 and assigns result back
value ^= 5;        // also bitwise XORs 5 and assigns result back

// |=
value | 5;         // bitwise ORs 5
value = value | 5; // bitwise ORs 5 and assigns result back
value |= 5;        // also bitwise ORs 5 and assigns result back
```

[p]: /zh-cn/book/types#primitive-types
[bool]: /zh-cn/book/types#booleans
[int]: /zh-cn/book/integers
[cell]: /zh-cn/book/cells#cells
[slice]: /zh-cn/book/cells#slices
