Swift SE-0372 解读官方承诺sort()为稳定排序从文档变更看标准库行为保证【免费下载链接】swift-evolutionThis maintains proposals for changes and user-visible enhancements to the Swift Programming Language.项目地址: https://gitcode.com/gh_mirrors/sw/swift-evolutionSE-0372Document Sorting as Stable是 Swift 标准库演进提案中少见的纯文档型提案——它不改任何算法与 API只是把早已是事实的行为正式写入文档承诺。本文以该提案为骨架结合 swift-evolution 仓库中的关联提案与演进背景系统讲解稳定排序stable sort的定义、sort()的实现现状、该保证对源码兼容性与 ABI 的意义以及多属性排序等真实应用场景。提案背景与核心结论SE-0372 的提案文本位于 proposals/0372-document-sorting-as-stable.md作者为 Nate Cook评审经理为 Tony Allevato状态为ImplementedSwift 5.8 落地。参考仓库 README.md 中的版本表Swift 5.8 于 2023-03-30 正式发布即该文档承诺随 5.8 一同生效。提案的核心主张非常直接Swift 的排序算法在 Swift 5 之前就已经被改为稳定排序但文档从未给出这一保证。让我们正式承诺排序算法是稳定的让开发者可以依赖该行为。换句话说这是一次将既有事实写进文档的规范化操作而不是引入新能力。什么是稳定排序Stable Sort稳定排序是指对于比较结果相等或无法比较的元素排序后保持它们原有的相对顺序。提案给出了一个极具代表性的例子——球员名单已按姓氏排序再按名字排序后两位名为 Ashley 的球员仍保持原来的先后次序Hatch 在 Sanchez 之前var roster [ Player(first: Sam, last: Coffey), Player(first: Ashley, last: Hatch), Player(first: Kristie, last: Mewis), Player(first: Ashley, last: Sanchez), Player(first: Sophia, last: Smith), ] roster.sort(by: { $0.first $1.first }) // roster [ // Player(first: Ashley, last: Hatch), // Player(first: Ashley, last: Sanchez), // Player(first: Kristie, last: Mewis), // Player(first: Sam, last: Coffey), // Player(first: Sophia, last: Smith), // ]若排序不稳定两次 Ashley 的相对位置可能被任意打乱结果变得不可预测。稳定性何时可被观察到提案明确指出排序稳定性并非总能被察觉当集合依据元素自身的Comparable一致性排序时例如排序一个整数数组相等的元素通常无法区分稳定性几乎不可见只有当元素基于其属性的子集进行排序时稳定性才产生可观察的差异。例如上面的球员示例若按完整身份名字姓氏比较两个 Ashley 并不相等稳定性无从谈起只有仅按first排序时first相等的两个元素才需要靠稳定性保持原始相对顺序。为什么稳定性符合直觉电子表格的多列排序提案提到一个重要的用户预期来源电子表格软件。在表格中先按某一列排序、再按另一列排序是完成多属性复合排序的惯用方式。这种操作能否得到预期结果完全依赖于每次排序的稳定性。开发者从这类工具迁移到编程语言时会天然期待排序保留相等元素的相对顺序而许多经典排序算法如快速排序并不稳定这种认知落差正是提案所指的surprising。现状问题行为早已稳定文档却明确否认提案引用了 Swift 5.7 标准库Sort.swift中一段著名的文档注释The sorting algorithm is not guaranteed to be stable. A stable sort preserves the relative order of elements that compare as equal.即文档明确声明不保证稳定但实现早就稳定了。这个状态造成了两类问题了解稳定性的开发者无法依赖当前行为——理论上任何一个 Swift 版本都可能修正文档而改用不稳定算法使依赖稳定性的代码静默出错不了解稳定性的开发者一旦稳定性在未来被移除他们的程序会突然出现难以排查的随机 bug。正式保证稳定性可以同时消除这两类风险。解决方案一处文档注释的变更由于 Swift 5 之前即 ABI 稳定之前就已引入稳定排序所有当前 Swift 运行时版本都自带稳定排序因此本提案只需修改标准库文档不涉及任何实现改动- /// The sorting algorithm is not guaranteed to be stable. A stable sort /// The sorting algorithm is guaranteed to be stable. A stable sort /// preserves the relative order of elements that compare as equal.这个 diff 是提案全文最核心的交付物体现了标准库行为承诺的本质sort()与sorted()自此获得正式的、可持续依赖的行为契约。与之配套的实现合入为 apple/swift 的 PR #60936。兼容性影响分析源码兼容性该变更只是把既有行为固化为契约因此对所有现有源码完全兼容——此前能编译运行的代码之后依然能编译运行且行为不变。ABI 稳定性稳定排序的实现在 ABI 稳定Swift 5 正式确立 ABI 稳定之前就已就位因此所有 ABI 稳定的 Swift 版本本来就已经提供该行为。对二进制层面毫无影响。API 韧性API resilience这是唯一产生约束的维度一旦做出明确保证未来任何对排序算法的修改都必须维持稳定性稳定性从实现细节升级为公共 API 契约的一部分。这正是把行为文档化的价值——它约束的是 Swift 团队未来的演进自由换取的是全体开发者的确定性。备选方案为什么不做unstableSort()讨论排序稳定性时自然会出现一个疑问既然稳定性这么好是不是也应该提供一个不稳定的排序变体unstableSort()提案给出了清晰的否决理由不稳定本身没有价值没有任何用户需要把相等元素打乱的排序用户真正感兴趣的可能是具有其他特性的算法例如只使用数组现有内存分配in-place、零额外分配的排序这类算法在不要求稳定的前提下更容易实现、性能更优若未来有人提出这类排序算法提案其不稳定性完全可以通过文档说明和/或 API 命名来传达例如在命名中显式体现非稳定特性无需让默认排序让步默认sort()保持稳定依然是最符合直觉、最安全的选择。未来方向排序生态的更多可能提案在结尾列举了若干值得继续探索的排序相关改进这些方向至今仍是 Swift 标准库演进的活跃话题key-path 或基于函数的排序允许直接按\.property这样的 key path 排序减少闭包样板有序集合类型或协议sorted collection types / protocols把始终有序提升为一等公民的数据结构能力排序描述符sort descriptors支持可组合、可复用的比较条件描述。值得注意的是仓库中已有若干与排序生态直接相关的历史提案可供交叉参考例如 SE-0074二分查找函数 提出的partitionedIndex(where:)、sortedIndex(of:)、sortedRange(of:)与partition(where:)它们都建立在集合已有序的前提之上——而有序的前提正是依赖sort()的确定性SE-0078rotate 算法 则探讨了与排序同属基础算法的旋转操作。这些提案共同勾勒出 Swift 在有序数据方向上的完整演进脉络。实践要点如何在代码中利用稳定性保证从 Swift 5.8 起你可以放心地在生产代码中依赖以下行为1. 多键复合排序两阶段排序先按次要键排序再按主要键排序稳定保证使两次排序的结果等价于一次多键排序players.sort(by: { $0.last $1.last }) // 次要键 players.sort(by: { $0.first $1.first }) // 主要键稳定保留上一步顺序2. 结合partition(where:)等 API 的有序集合操作当使用 SE-0074 讨论的partitionedIndex(where:)这类算法时其正确性要求集合元素已按谓词完成分区或有序排列稳定的sort()是构建这一前提的可靠工具。3. 无额外依赖的排序链sort()原地与sorted()返回新数组共享相同的稳定性契约因此以下写法同样是安全的let stable players.sorted { $0.score $1.score }小结SE-0372 是 Swift Evolution 进程中文档即契约理念的典型样本它以一行文档注释的变更把 Swift 社区长期默认的稳定排序行为正式化消除了标准库行为与文档表述之间长达数个版本的鸿沟。对开发者而言从 Swift 5.8 起sort()是稳定排序不再是一个碰巧成立的实现细节而是一条可以放心依赖、写进任何业务逻辑与算法假设的官方承诺。【免费下载链接】swift-evolutionThis maintains proposals for changes and user-visible enhancements to the Swift Programming Language.项目地址: https://gitcode.com/gh_mirrors/sw/swift-evolution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
抖音pc端源码解析:3个坑让你面试不再卡壳 抖音pc端源码解析:3个坑让你面试不再卡壳 上周陪一个朋友模拟面试,面试官问:“你做的抖音PC端项目,视频加载时内存暴涨怎么优化的?”他愣了五秒,只答出“加了懒加载”。这场景太熟悉了。很多前端转后端或全栈的同学,平时只盯着页面渲染,一旦追问… · 2026/9/23 19:19:29
3个步骤搞懂火热的死亡:前端避坑指南 3个步骤搞懂火热的死亡:前端避坑指南 刚学完 if-else 和循环,代码能跑,一搭项目就崩?别慌,这几乎是每个开发者的必经之路。很多新手卡在“语法会写,项目不会搭”的鸿沟里,反复查文档却找不到头绪。这篇避坑指南不讲虚的,直接拆解一个典型故… · 2026/9/23 20:21:26
意间AI绘画手写实现:3步搞定项目搭建避坑指南 意间AI绘画手写实现:3步搞定项目搭建避坑指南 刚毕业那会儿,我拿着Python语法书,看着满屏的 def 和 class ,脑子是清醒的,但手是废的。为什么?因为 学会语法却不知怎么搭项目 。你懂 for… · 2026/9/23 20:21:20
面试突击:手写实现“头很痛怎么办”背后的算法逻辑 面试突击:手写实现“头很痛怎么办”背后的算法逻辑 是不是感觉脑子像浆糊一样,看了一堆教程还是不会写项目?别慌,这其实是大多数开发者的通病。很多兄弟在掘金技术社区发帖吐槽,说面试时遇到“头很痛怎么办”这种看似无厘头的问题,直接懵圈。其实,这根… · 2026/9/23 20:20:59
华为浏览器下载源码图解原理与实战拆解 华为浏览器下载源码图解原理与实战拆解 学会语法却不知怎么搭项目?这是很多初学者的通病。看着文档里的 download() 方法,心里没底,不知道底层到底发生了什么。今天咱们不聊虚的,直接通过 图解原理… · 2026/9/23 20:20:44
2026最新李连杰海啸版本升级避坑指南:API全变后如何快速恢复 2026最新李连杰海啸版本升级避坑指南:API全变后如何快速恢复 版本升级后 API 全变了,项目直接崩盘,这是很多老手和新人都没预料到的噩梦。2026最新的李连杰海啸(Li Jianjie Tsunami,简称 LJT)框架在 3.0… · 2026/9/23 20:20:37
智能体编程基本设计 智能体分层架构与抽象接口设计汇总本文汇总内容:智能体框架现状、BaseAgent 抽象基类、两种架构对比(Agent→Tool / Agent→Skill→Tool),可直接保存为 agent_arch.md目录
智能体编程接口现状:无全局统一标准方案A&… · 2026/9/23 20:20:30
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29