# 9. 函数与调用 函数定义可调用的逻辑,包括名称、输入参数、结果类型和函数体。调用表达式提供输入,并取得函数定义的结果。 discountedPrice 是 Function 的实例,Function 类型对象是 Type 的实例并继承 Object。以下采用 function 构造记法的候选简写说明基本调用;具体函数类型的构造必须另有明确的类型位置。自身类型标注及生命周期扩展示例见[Function](07-top-level-types/functions.md)。 ## 9.1 函数声明 代码归属:`atelier:shop.pricing`。 ```endorphin function discountedPrice(price: Number, discount: Number): Number { return price - discount } ``` 声明的组成如下: | 部分 | 含义 | | --- | --- | | `function` | 函数对象构造的候选记法 | | `discountedPrice` | 函数名 | | `price: Number, discount: Number` | 两个输入参数及其类型 | | 参数列表后的 `: Number` | 返回类型 | | 花括号内的内容 | 函数体 | 参数按逗号分隔,每个参数都有名称与类型。本文基本函数体由零个或多个 let 绑定和一个末尾 return 组成;完整控制流另列于[规范状态](../appendices/specification-status.md#声明与类型)。 ## 9.2 返回值 `return 表达式` 产生函数结果。表达式的类型必须符合返回类型。 discountedPrice 返回两个数值的差值。对于输入 `100` 与 `10`,成功结果为 `90`。定义函数不立即执行它;执行发生在 inflight 调用中。 ## 9.3 跨 namespace 调用 代码归属:`market:shop.checkout`。 ```endorphin use atelier:shop.pricing function payable(price: Number, discount: Number): Number { let amount = discountedPrice(price, discount) return discountedPrice(amount, 5) } ``` payable 引用定价 namespace,先使用原价与优惠额计算 amount,再从 amount 中扣除 `5`。对于输入 `100` 与 `10`,两次成功结果依次为 `90` 和 `85`。 该例采用第 4 章所述的无名称冲突、被引用函数可见的条件。use 定位依赖来源,函数调用使用其中的逻辑;二者分别承担引用和执行职责。 ## 9.4 调用组合 代码归属:`market:shop.ui`。业务函数声明: ```endorphin use market:shop.checkout function checkoutAmount(): Number { return payable(100, 10) } ``` checkoutAmount 的成功结果为 `85`。它不需要重复实现价格计算,也不需要为跨 namespace 调用另写客户端、网络请求或编排配置。 相同的普通调用形式用于本地逻辑和跨执行位置的逻辑。执行位置和通信方式不改变输入、结果类型与数据依赖。 ## 9.5 Preflight 检查 在名称和类型规则确定的范围内,Preflight 检查: - 调用目标是否存在且允许使用。 - 参数数量和类型是否符合声明。 - return 表达式是否符合返回类型。 - 使用调用结果的后续表达式是否合法。 例如,discountedPrice 需要两个数值参数。`discountedPrice(100)` 数量不符;`discountedPrice("100", 10)` 在本文不进行隐式文本到数值转换的示例条件下类型不符。 ## 9.6 inflight 行为 inflight 使用实际参数执行函数,并把成功结果交给调用表达式。依赖关系必须保留:payable 的第二次优惠计算使用第一次调用的 amount。 | 情况 | 行为要求 | | --- | --- | | 调用成功 | 结果的值和类型符合函数定义 | | 结果未就绪 | 依赖该结果的代码不能提前将它作为成功值使用 | | 调用失败 | 失败可被观察,不伪造成功结果 | | 执行位置变化 | 已定义的值、类型、依赖与业务效果保持一致 | 函数不默认被视为纯计算。对带业务修改效果的调用,系统不能为了执行组织而任意重复或并行执行;相关顺序、失败和取消语义见[规范状态](../appendices/specification-status.md#调用与数据)。 ## 9.7 函数查看与结果呈现 客户端可以将函数本身作为资源查看,也可以在输入满足要求后调用函数。查看定义不会取得函数返回值;调用成功后,结果才可按类型呈现或供后续计算使用。 界面逻辑使用同样的 function、表达式与 return 规则。可渲染结果的正式类型和构造形式尚未定义;本章普通函数示例不因此获得专用 UI 语法。 参数未就绪、调用等待和结果呈现的主要规则见[资源访问与呈现](11-resource-access-and-presentation.md)。源码中缺少必填参数的调用与客户端查看函数定义属于不同情况。 [上一章:表达式与绑定](08-expressions-and-bindings.md) · [下一章:数据读取](10-data-access.md) · [目录](../README.md)