Sway 中的 Never 类型(`!`):永不产生值的类型及其在智能合约中的实战用法

发布时间:2026/9/12 6:56:14
Sway 中的 Never 类型(`!`):永不产生值的类型及其在智能合约中的实战用法 Sway 中的 Never 类型!永不产生值的类型及其在智能合约中的实战用法【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/swayNever 类型写作!是 Sway 中一类特殊类型它表示永远不会解析出任何值的计算结果。本指南以官方文档 never_type.md 为核心骨架结合 Sway 标准库与编译器源码系统讲解!类型的语义、break/continue/return/revert等发散表达式的行为、!向任意类型自动强转的机制以及在match分支中利用!类型编写安全、简洁的智能合约代码的实战方案。Never 类型是什么在 Sway 中Never 类型!表示永远不会解析为任何值的计算类型。它是一种「无人居住」uninhabited的类型不存在任何属于!类型的值因此一个类型为!的表达式不可能正常返回——它要么使控制流转移如return跳出函数、break跳出循环要么直接终止程序如revert()要么无限循环下去。从编译器源码看Sway 类型系统在 info.rs 的TypeInfo枚举中定义了Never变体并在显示层将其渲染为!见 info.rs。同时info.rs 中is_uninhabited的实现把TypeInfo::Never直接判定为无人居住类型返回true这正是!语义的编译器级依据一个!类型的表达式在运行时不可能产生任何值。哪些表达式具有!类型文档明确指出break、continue和return表达式也具有类型!。例如下面这段代码是合法的let x: ! { return 123 };虽然这里的let绑定毫无实际意义x永远不可能被赋值但它精确地揭示了!的含义因为return 123会从整个函数返回x永远不会被赋上任何值所以x可以被赋予!类型。除了return我们还可以把上面的return 123替换为revert()或者一个永不结束的loop代码依然是合法的——因为它们同样属于发散diverging表达式永远不会产生值。return立即从当前函数返回后续代码不再执行故表达式类型为!。break/continue在循环中转移控制流不产生值类型为!。revert()无条件回滚合约状态必然终止当前执行返回类型为!。永不终止的loop如果循环体没有break路径该循环表达式永远不会完成求值类型为!。循环中break/continue的实战示例仓库中的 break_and_continue 示例 展示了二者在真实脚本中的用法。break用于在counter num时提前跳出循环fn break_example() - u64 { let mut counter 1; let mut sum 0; let num 10; while true { if counter num { break; // 类型为 !提前终止循环 } sum counter; counter 1; } sum // 1 2 .. 10 55 }continue用于跳过偶数次迭代fn continue_example() - u64 { let mut counter 0; let mut sum 0; let num 10; while counter num { counter 1; if counter % 2 0 { continue; // 类型为 !跳过后续累加 } sum counter; } sum // 1 3 .. 9 25 }主函数将二者结果相加break_example() continue_example()即55 25 80。!类型向任意其他类型自动强转Never 类型最实用的特性是强转coercion类型为!的表达式可以自动强转为任何其他类型。原因很直观一个永远不会产生值的表达式自然也不可能产生一个不符合目标类型的值——它压根不产生值。文档给出的例子let x: u32 { return 123 };无论x声明为何种类型类型为Never的return块总是能强转为x的类型。这一机制使得!可以在任何需要具体类型值的上下文中充当占位而编译器不会报类型不匹配错误。从实现层面看编译器把 Never 当作可复制copy类型处理。在 fuel_asm_builder.rs 的is_copy_type中ty.is_never(self.context)与is_unit、is_bool等并列说明!类型在代码生成阶段被视为零成本、无需搬移值的类型。此外在 ABI 生成中Never被映射为字符串never见 abi_str.rs 与 evm_abi.rs表明该类型在跨 ABI 描述中也有规范的表示。实战用法利用!简化 match 分支Never 类型最常见的实战场景出现在match表达式中。文档给出的典型例子let num: u32 match get_a_number() { Some(num) num, None break, };这里match的两个分支本应都产生u32类型的值但None分支写的是break。由于break的类型是!而!可以强转为u32因此这段代码完全合法。更重要的是它的语义非常安全当遇到None时直接跳出当前循环根本不存在返回一个非u32值的可能性。这种写法在智能合约开发中非常实用当数据不满足前置条件时与其构造一个哨兵值如0或u64::MAX不如直接用break/return/revert让执行流退出既减少了错误值的传播也避免了额外的if判断。组合Option与return的完整示例文档末尾的完整示例把match、Option与!类型组合在一起fn foo() { let num: u64 match Option::None::u64 { Some(num) num, None return, }; }当Option为None时return类型!直接结束函数否则解出num作为u64值使用。Option类型本身是 Sway 标准库中的一等公民在 option.sw 中有完整定义其典型用途包括可选的函数参数、错误返回等常与模式匹配配合使用。用revert替代break做安全检查在合约上下文中遇到异常即回滚比跳出循环更常见。标准库 revert.sw 中revert的签名本身就印证了它与!的关系pub fn revert(code: u64) - ! { __revert(code) }revert的返回类型就是!这意味着它可以被用在任何需要返回值的表达式位置。例如let num: u64 match get_a_number() { Some(num) num, None revert(42), // 类型为 !直接回滚绝不可能返回非 u64 值 };这同样利用了!强转的机制同时比break更适合合约语义None被视为致命错误直接回滚整个交易。标准库还提供了require(condition, value)见 revert.sw它在条件不满足时记录日志并调用revert(FAILED_REQUIRE_SIGNAL)是!发散语义在合约校验中的进一步封装。标准库对!类型的扩展实现Never 类型并不是孤立存在的。Sway 标准库在 never.sw 中为!实现了多个核心 trait进一步拓展了它的可用性impl Not for ! { fn not(self) - Self { match self {} // 对无人居住类型做空模式匹配 } } impl PartialEq for ! { fn eq(self, _other: Self) - bool { self } } impl Eq for ! {} impl Ord for ! { fn gt(self, _other: Self) - bool { self } fn lt(self, _other: Self) - bool { self } }注意这些实现中大量使用了match self {}——由于!是无人居住类型没有任何值可以匹配因此编译器认为该match已经穷尽了所有不存在的可能分支。这是空模式匹配exhaustive empty match的典型用法从侧面印证了!的无人居住特性。同时prelude.sw 中通过pub use ::never::*;将never模块的内容导入预导出prelude这意味着在大多数 Sway 项目中无需显式use即可直接使用这些 trait 实现。注意事项与常见误区!不是任意类型!本身是一个具体类型它的值不存在它强转为任意类型针对的是表达式类型为!的场景而非把所有类型都变成!。let x: ! ...只是教学演示实际代码中不应刻意绑定!类型变量它的价值体现在match分支、函数返回值、revert等需要占位或发散的上下文。发散表达式后面通常不可达return、revert()之后的代码不会执行编译器会据此进行控制流分析仓库中 dead_code_analysis.rs 对Never返回类型的条件节点有专门处理不要在发散表达式后假设还能执行到。loop只有永不终止才算!如果loop内部存在break路径其表达式类型是break之后的值类型而非!。小结Never 类型!是 Sway 类型系统中永不产生值这一概念的精确表达break、continue、return、revert()与永不终止的loop都是它的来源它向任意类型的自动强转让match分支可以安全、简洁地处理异常即退出的逻辑编译器在类型系统TypeInfo::Never、is_uninhabited、代码生成is_copy_type与 ABI 描述层面对其都有完备支持。掌握!类型是写出健壮、优雅的 Sway 智能合约代码的重要一步。【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询