93 lines
4.4 KiB
Markdown
93 lines
4.4 KiB
Markdown
# 8. 表达式与绑定
|
||
|
||
表达式描述计算并产生值。let 将表达式结果绑定到局部名称,后续表达式可以使用这个结果。
|
||
|
||
## 8.1 表达式形式
|
||
|
||
本文语法包含以下表达式:
|
||
|
||
| 形式 | 示例 | 含义 |
|
||
| --- | --- | --- |
|
||
| 字面量 | `100`、`"商品"`、`.title` | 直接表达一个值 |
|
||
| 名称引用 | `amount` | 使用已解析的名称 |
|
||
| 一元表达式 | `-4` | 对值使用一元负号 |
|
||
| 算术表达式 | `100 - 10` | 计算数值 |
|
||
| 成员访问 | `product.price` | 使用字段或成员 |
|
||
| 调用 | `discountedPrice(100, 10)` | 调用逻辑并取得结果 |
|
||
| 分组 | `(100 - 10) * 2` | 改变表达式组合方式 |
|
||
|
||
具体名称和成员必须存在并符合类型要求。调用的参数和返回规则见[函数与调用](09-functions-and-calls.md)。
|
||
|
||
## 8.2 运算与优先级
|
||
|
||
从高到低的组合顺序为:
|
||
|
||
| 顺序 | 形式 |
|
||
| --- | --- |
|
||
| 1 | 分组中的表达式 |
|
||
| 2 | 成员访问与调用 |
|
||
| 3 | 一元负号 |
|
||
| 4 | 乘法、除法 |
|
||
| 5 | 加法、减法 |
|
||
|
||
同级二元算术运算在本文草案中按从左到右组合。`100 - 10 * 2` 先做乘法,结果为 `80`;`(100 - 10) * 2` 的结果为 `180`。
|
||
|
||
数值采用统一类别,不按固定机器位宽定义溢出;精度、除法、舍入、隐式转换和其他运算符的规则见[规范状态](../appendices/specification-status.md#词法与表达式)。
|
||
|
||
## 8.3 let 绑定
|
||
|
||
函数体片段:
|
||
|
||
```endorphin
|
||
let amount = 100 - 10
|
||
let payable = amount - 5
|
||
```
|
||
|
||
第一行将结果 `90` 绑定到 amount,第二行使用它得到 `85`。每个绑定包含关键字 `let`、局部名称、等号和表达式。
|
||
|
||
let 是结果绑定,不是 namespace 声明。变量可以改变引用目标的模型见 8.6;本节 let 示例只展示初始绑定,不据此决定 let 是否允许重绑、重新赋值的源码形式或顶层绑定规则。
|
||
|
||
## 8.4 成员访问
|
||
|
||
`值.成员名` 访问该值的字段或其他可用成员。类型检查决定访问是否合法。
|
||
|
||
`product.price` 使用 Product 的字段。`Product.get(...)` 则在形式上是先找到类成员,再调用;成员调用的形式不会自动为 Product 创建 get 方法,详见[数据读取](10-data-access.md)。
|
||
|
||
## 8.5 结果依赖
|
||
|
||
当一个表达式使用前一个调用的结果时,存在数据依赖:
|
||
|
||
```text
|
||
第一次调用 → 结果绑定 → 使用该结果的第二次调用
|
||
```
|
||
|
||
inflight 必须在结果可用后使用它,不能将未就绪状态替换为伪造成功值。Preflight 检查表达式结构与类型,不能据此保证所有实际调用成功。
|
||
|
||
表达式是否带有业务修改效果,以及失败、等待与取消的表示方式,由调用语义定义。算术的组合顺序不自动确定所有调用参数的求值顺序。
|
||
|
||
## 8.6 变量与资源引用
|
||
|
||
变量保存对资源的引用,并可以在类型和作用域规则允许时改变引用目标。它可以引用数值、文本或媒体等基础常量,也可以引用函数、class、agent 及其可用实例。引用声明不会自动调用函数或创建实例。
|
||
|
||
下面是语义示意,不是赋值语法:
|
||
|
||
```text
|
||
价格变量 → 数值常量 100
|
||
改变引用目标
|
||
价格变量 → 数值常量 90
|
||
|
||
图片变量 → 原图片资源
|
||
改变引用目标
|
||
图片变量 → 处理后产生的新图片资源
|
||
```
|
||
|
||
这里变化的是变量的目标,原数值和原图片内容没有被原地修改。多个变量引用同一常量时,一个变量改指新值不要求其他变量同时改变目标。
|
||
|
||
高级结构可以通过成员变量组织资源引用;实例状态的变化与基础内容的不可变性可以同时成立。实例整体的可变性、字段更新、引用别名和相等性仍需明确规则,不由“变量类似指针”推导出裸地址或指针算术。
|
||
|
||
变量的创建、使用和引用更新属于 inflight。类型与作用域的准备属于 Preflight;变量或实例不再需要时的回收,以及保存后如何删除,见[生命周期](05-preflight-and-inflight.md#56-定义与运行时生命周期)。
|
||
|
||
可变变量的声明与重新赋值写法、引用类型和 let 的可重绑性尚未定义,其状态记录在[基础资源与变量](../appendices/specification-status.md#基础资源与变量)。
|
||
|
||
[上一章:资源、类型与类](07-types-and-classes.md) · [第 7 章续篇:类型系统](07-top-level-types/README.md) · [下一章:函数与调用](09-functions-and-calls.md) · [目录](../README.md)
|