文档【免费下载链接】swift-evolutionThis maintains proposals for changes and user-visible enhancements to the Swift Programming Language.项目地址https://gitcode.com/gh_mirrors/sw/swift-evolution点击查看免费下载导读SE-0538Disconnected类型为 Swift 并发模型引入了一个新的标准库包装类型它能把值处于断开区域disconnected region这一性质穿透存储边界泛型容器、存储属性、队列等保存下来使非Sendable值无需经过sending标注即可在隔离区域之间安全传输。读完本文你将理解 region-based isolation 与sending的边界局限、Disconnected的完整 API 设计与安全不变量init/consume()/exchange/withValue、它为何能无条件符合Sendable以及各备选方案borrow 访问器、协议化、sending泛型参数等被否决的深层原因。背景从 Region-based Isolation 到sendingSE-0538 建立在此前两个提案之上理解它们是理解Disconnected的前提。SE-0414隔离区域Isolation RegionSE-0414 region-based isolation已实现于 Swift 6.0引入了控制流敏感的诊断编译器把程序运行期存在的值划分成若干隔离区域——两个值 $x$、$y$ 在同一程序点 $p$ 属于同一隔离区域当且仅当 $x$ 可能别名 $y$或 $x$ 可能通过 $y$ 的属性链访问被 $y$ 引用。处于不同隔离区域的非Sendable值可以并发使用因为任何使用 $x$ 的代码都不可能影响 $y$。一个值处于断开区域disconnected region时没有任何引用从其他区域到达它的存储、也没有引用从它的存储伸出到其他区域。这样的值可以安全转移到另一个隔离区域actor、Task、其他并发上下文因为转移过程不可能制造数据竞争。SE-0414 允许在值处于断开区域且转移后不再被使用的前提下把非Sendable值跨隔离边界传递从而避免大量依赖unchecked Sendable逃生舱的写法。SE-0430sending参数与结果标注SE-0430 transferring parameters and results 引入了sending标注在函数边界上显式表达此值必须处于断开区域public func withCheckedContinuationT( function: String #function, _ body: (CheckedContinuationT, Never) - Void ) async - sending Tsending参数要求调用方传入的值处于断开区域调用点之后该断开区域不再属于调用方的隔离域被调方可以把它发送到调用方无法感知的区域。sending结果要求函数实现返回一个处于断开区域的值调用方可以假定结果在断开区域从而让非Sendable类型的结果跨过 actor 隔离边界。子类型规则sending T是T的子类型sending在参数位置逆变、在结果位置协变。sending描述的是值在函数边界上的属性一次转移事件而不是类型本身的稳定属性。关键局限随之而来。Motivationsending无法穿透存储考虑一个跨隔离边界处理元素的队列实现——提案中的假设类型UniqueDequestruct UniqueDequeElement: ~Copyable: ~Copyable { func append(_ element: consuming Element) { ... } func popFirst() - Element? { ... } }一个典型用法是把非Sendable的断开值 append 进队列弹出后发送到另一个隔离区域var deque UniqueDequeNonSendable() deque.append(NonSendable()) guard let element deque.popFirst() else { return } Task { print(element) // Error: Element is assumed to be in the same isolation region as uniqueDeque }上面会报错因为Element被视为与uniqueDeque处于同一隔离区域。要让代码通过需要让append以sending消费元素、让popFirst以sending返回元素——但这会严重限制该类型其他同样重要的用途用户可能想存储非Sendable但并非断开的元素。根本局限在于sending是函数边界的属性不是类型的属性。泛型类型如UniqueDeque无法根据条件决定存储的元素是否应保持断开状态若把append/popFirst都标成sendingUniqueDeque就只能存放断开值了。这正是 SE-0430 的 Future directions 部分 所预告的缺口sending要求值在函数边界处于断开区域但没有任何办法把值处于断开区域这个信息保存下来穿过存储属性、集合、函数调用等结构。Proposed solution用Disconnected包装类型保存断开属性SE-0538 引入Disconnected类型来建模断开的值让泛型容器无需关心sending效应即可安全转移非Sendable值var deque UniqueDequeDisconnectedNonSendable() deque.append(Disconnected(NonSendable())) guard var disconnected deque.popFirst() else { return } let element disconnected.consume() Task { print(element) }Disconnected包装一个值确保它始终留在断开区域内consume()方法消费包装器以sending返回内部值使其能够跨越隔离边界。队列本身不再需要任何sending标注——断开信息由包装类型携带而非依赖函数签名。Detailed designDisconnected的完整 APIDisconnected是一个frozen的结构体位于标准库的Synchronization模块与Mutex、Atomic等跨隔离边界的原语并列完整签名如下frozen public struct DisconnectedValue: ~Copyable: ~Copyable, Sendable { public init(_ value: consuming sending Value) public consuming func consume() - sending Value discardableResult public mutating func exchange( newValue: consuming sending Value ) - sending Value public mutating func withValueReturn: ~Copyable, Failure( body: (inout sending Value) throws(Failure) - Return ) throws(Failure) - Return }什么是断开区域Region-based isolation 依据哪些引用可达哪些存储把程序执行中任意时刻的值划分为隔离区域。值处于断开区域时没有引用从任何其他区域伸入或伸出它的存储把这样的值转移到另一个隔离区域不会产生数据竞争。实践中断开区域通常来自新建的值其初始化参数本身处于断开区域刚从另一个断开容器中移除的值函数边界的sending参数被调方在断开区域中接收函数返回的sending结果调用方在断开区域中接收。断开属性通常只在sending边界被跟踪DisconnectedValue让它可以穿过泛型容器、存储属性、队列等本会丢失区域信息的存储边界。init(_:)值进入包装器的唯一入口init要求参数为consuming sending Value即调用点的实参必须处于断开区域。新构造、无别名的值天然满足该要求final class Resource: ~Sendable {} let wrapper Disconnected(Resource())包装器接管值的所有权consuming并在整个存储期间维持其断开属性。consume()取出并转移consume()消费包装器本身consuming返回sending Value——返回值处于断开区域可以在同一表达式中跨隔离边界转移也可以先存储再转移final class Resource: ~Sendable {} // wrapper 从持有 DisconnectedResource 的队列或其他容器中弹出 // 因此它包裹的资源已被确认与周围上下文断开。 func process(wrapper: consuming DisconnectedResource) async { let resource wrapper.consume() await Task.detached { use(resource) // OK: resource 处于断开区域。 }.value }若没有结果上的断开保证被捕获的resource会被视为调用方区域的一部分上述 detached task 中的捕获将不被允许。consume()返回后包装器已被消费无法再执行任何操作。exchange(newValue:)原地置换exchange一步完成放入新值、取回旧值newValue必须处于断开区域返回的旧值同样处于断开区域final class Resource: ~Sendable {} func exchangeResources(in wrapper: inout DisconnectedResource) async { let old wrapper.exchange(newValue: Resource()) await Task.detached { dispose(old) // OK: old 处于断开区域。 }.value }置换的两个方向都跨越断开区域边界新值进入时必须断开旧值出来时已知断开。withValue(body:)原地可变访问需要临时可变访问而不取出值时使用withValue。闭包以inout sending Value接收值withValue返回闭包的返回值var wrapper Disconnected([Int]()) wrapper.withValue { array in array.append(42) }inout sending参数形态比普通inout含义更强在闭包内部值可以转移到另一个隔离区域只要闭包返回时包装器仍持有一个断开值。典型用法是原地修改更宽松的形态使withValue能与想把值发送到其他隔离区域的代码组合。若body抛错包装器保留闭包最后留在存储中的值错误传播给调用方。为什么Disconnected无条件符合SendableDisconnected保证其包裹值处于断开区域断开区域可以安全地跨隔离边界转移因此无论T是否符合SendableDisconnectedT都可以安全共享。此外Disconnected的所有方法要么是consuming要么是mutating编译器会强制执行静态与动态排他性检查exclusivity checking禁止重叠与并发访问——这是Sendable一致性成立的关键一环。API 刻意被限制为sending边界上的原子转移init消费一个sending值consume消费包装器并返回sending值exchange用另一个sending值置换withValue在闭包存活期内以inout sending出借值。不存在任何不消费、不置换就暴露包裹值的访问器——正如 Alternatives 一节所述borrow 访问器在无条件Sendable一致性下是不健全unsound的。兼容性与采纳影响Source compatibility本提案向标准库新增一个类型不修改现有代码无源兼容性影响。ABI compatibility新增frozen类型Disconnected的布局 ABI 稳定不影响既有 ABI。Implications on adoption需要新版本的 Swift 标准库与运行时才能使用。Alternatives considered为什么其他方案被否决备选命名Nonisolated、DisconnectedRegion曾被考虑最终Disconnected最贴切且断开区域概念由 SE-0414 先行引入。基于sending/Sendable词汇的SentValue、SendingValue也被提议但被否决sending描述的是值在函数边界上的属性一次转移事件而非稳定的区域状态一个仅仅持有生活在断开区域的值的包装器并不处于转移中途用转移事件命名会误导读者。SE-0414 引入的断开区域概念才是包装器真正维持的不变量沿用该名称保持词汇与既有隔离模型一致。在泛型参数上使用sending标注与其引入包装类型也可以尝试让泛型类型参数化元素是否为sending。但这需要大量语言改动来支持基于泛型约束的条件式sending应用并使泛型签名复杂化。包装类型方案无需任何语言改动仅靠库新增即提供等价功能。把Disconnected做成协议协议方案可以应用于既有类型但需要证明符合类型的所有值都处于断开区域——这对可变类型无法强制执行。包装类型方案通过构造提供更强保证。暴露包裹值的 borrow 访问器添加borrow访问器如public var value: Value { borrow }会很符合人体工程学也能与 SE-0519Ref/MutableRef类型 的借用访问器自然组合持有DisconnectedValue元素的容器会产出RefDisconnectedValue投影。但任何此类访问器在无条件Sendable一致性下都是不健全的Sendable一致性告诉类型检查器包装器可以在隔离区域间转移而无需区域跟踪从包装器中复制出携带引用的非Sendable值会创建编译器无法关联回包装器的别名。提案给出了竞争示例final class Box { var state 0 } struct Foo { let box: Box } actor A { func test() { let disconnected Disconnected(Foo(box: Box())) let escaped disconnected.value.box // 把类引用复制进 actor A 的区域 Task.detached { var d consume disconnected // Sendable因此被允许 d.consume().box.state 1 // detached task 触碰 Box } escaped.state 1 // actor A 触碰同一个 Box // race } }编译器允许把disconnected转移进 detached task类型是Sendable却没有意识到escaped别名了包装器内部的存储。基于 SE-0519 的var ref: RefValue { borrow }投影存在同样的漏洞var mutableRef: MutableRefValue { mutate }投影甚至更糟——MutableRef.value的 setter 接受当前区域内任意Value而无sending约束会允许通过赋值直接合并区域。提案 API 通过只允许sending边界上的原子转移避开了整类问题每个操作要么消费包装器要么用另一个sending值置换因此任何指向包装器存储的别名都无法比一次转移活得更久。健全的 borrow/mutate 式 API 要么需要让Disconnected条件性Sendable这违背其目的要么需要新的语言支持来跟踪从无条件Sendable包装器投影出的值的区域。Value: Sendable时的只读访问器当Value自身符合Sendable时读取访问器的健全性论证不适用读取Sendable包裹值暴露的引用已经活在可安全共享的区域投影出来不会产生数据竞争。因此曾考虑条件扩展extension Disconnected where Value: ~Copyable Sendable { public var sendableValue: Value { borrow } }该访问器最终未纳入目前没有出现令人信服的用例——对Value: Sendable泛型的代码已经可以通过consume()或exchange(newValue:)解包并直接操作对具体DisconnectedTT: Sendable的代码可以直接使用T无需经过包装器。按一致性拆分 API 表面还会迫使调用方记忆哪些操作可用、迫使泛型代码在约束变化时迁移。提案保持 API 对所有Value类型统一。若未来出现直接读取Sendable载荷的具体用例可在不破坏源/ABI 兼容性的前提下于后续版本添加。要求withValue的闭包返回sendingSE-0433Mutex的withLock声明闭包参数为(inout sending Value) throws(E) - sending Result并把sending Result传播到外层返回。为withValue考虑过平行签名public mutating func withValueReturn: ~Copyable, Failure( body: (inout sending Value) throws(Failure) - sending Return ) throws(Failure) - sending Return该方案被否决因为非sending的Return严格更具表达力。需要支持两种闭包形态返回从包裹值派生、用于跨隔离边界转移的值返回与调用方区域绑定的值例如与包裹值一起使用的、被捕获的非Sendable值。第一种形态在任一签名下都可表达非sendingReturn通过从闭包返回DisconnectedT来编码第二种形态只能在非sendingReturn下表达——已在调用方区域的值无法在sending边界返回。健全性担忧已由inout sending Value参数覆盖返回别名进入包裹存储的值的闭包会在退出时让该存储留下跨区域引用违反参数上的sending不变量并产生编译期错误与返回声明方式无关。与Mutex.withLock的不对称反映了用途差异Mutex保护共享状态withLock的主流模式是从加锁状态中提取值供临界区外使用sending Result自然契合Disconnected是活在调用方区域的自有包装器withValue需要支持混合包裹值状态与调用方状态的闭包。支持~Escapable值当前设计把Disconnected限制在可逃逸escapable类型上。断开区域属性概念上独立于生命周期依赖放宽Value约束、让Disconnected条件性Escapable很诱人struct DisconnectedValue: ~Copyable ~Escapable: ~Copyable, ~Escapable, Sendable { ... } extension Disconnected: Escapable where Value: Escapable {}但该泛化实践中无益。SE-0446 引入的不可逃逸类型 是对某源存储有生命周期依赖的非自有视图例如MutableSpanElement借用自ArrayElement带来两个问题源头不存在sending形态视图类型由返回依赖self生命周期值的借用访问器产生没有可消费的sending访问器Disconnected(array.mutableSpan)根本无法构造。生命周期源头不会随包装器移动即使能产生sending视图视图仍携带指向他处存储的引用。把DisconnectedMutableSpanInt转移到另一个隔离区域会让底层的Array留在原地构造性地违反断开区域属性——泛型包装器无从得知生命周期源头是什么、也无从携带它。结语Disconnected在 Swift 并发工具箱中的位置Disconnected是对 SE-0430 未来方向的落地它让断开从函数边界的瞬时属性升格为类型层面的稳定不变量使AsyncSequence等类型可以把非Sendable类型的缓冲元素作为sending返回而无需在实现中诉诸不安全的 opt-out。它与Synchronization模块中的Mutex、Atomic并肩为跨隔离边界传输非Sendable值这一需求提供了类型安全的正规通道。完整的标准库实现位于 swiftlang/swift#89597状态为Accepted。赞分享文档【免费下载链接】swift-evolutionThis maintains proposals for changes and user-visible enhancements to the Swift Programming Language.项目地址https://gitcode.com/gh_mirrors/sw/swift-evolution点击查看免费下载相关推荐Swift Evolution SE-0331 解读从不安全指针类型上移除 Sendable 一致性Swift Evolution SE 0331 解读从不安全指针类型上移除 Sendable 一致性 SE 0331Remove Sendable conf文档Swift SE-0518 深度解析用 ~Sendable 显式标记非 Sendable 类型Swift 6.4Swift SE 0518 深度解析用 ~Sendable 显式标记非 Sendable 类型Swift 6.4 ~Sendable 是 Swift 6.文档Swift Evolution SE-0335 提案解读为 Swift 引入显式存在类型关键字 anySwift Evolution SE 0335 提案解读为 Swift 引入显式存在类型关键字 any 本指南围绕 Swift Evolution 仓库中的文档上一篇Laguna-S-2.1-oQ2e与原生模型对比MMLUPro 70.3%/MathQA 84.0%精度测试报告下一篇doc_wei/erp-pro小程序开发技巧深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
基于内容过滤的居家健身推荐系统:Python与Flask实现与调优 简介:这是一份面向高校人工智能、计算机及相关专业学生的个性化居家健身推荐系统项目,基于Python Flask框架与基于内容的过滤算法开发。系统通过解析用户健身目标、体能水平与可用设备,智能推荐相适应的锻炼方案,能够缓解居家健身… · 2026/9/23 17:26:52
个性化智能体强化学习框架实战:基于8B模型的训练与优化 说实话,这个项目标题里每一个字我都想展开写。智能体、强化学习、框架、8B模型,这四个词单独拎出来都是能写一整年的方向,合在一起做成一个能上线、能跑、能打赢盲测的完整项目,背后要踩的坑和要做的取舍,远比标题看上… · 2026/9/23 17:26:52
电塔鸟巢检测数据集:1165张VOC+YOLO双格式与YOLOv8微调实战 简介:面向电塔上鸟巢检测场景的专业目标检测数据集,提供Pascal VOC与YOLO两种主流标注格式,便于直接用于YOLO系列、Faster R-CNN等常见检测模型的训练,也可服务于生态观测、电网安全巡检等实际项目。压缩包整体约87.32MBÿ… · 2026/9/23 17:26:52
Huff0 熵压缩库深度解析:wandb-core 中 zstd 的 Huffman 编码实现与实战使用 机器学习深度学习数据可视化可观测性 【免费下载链接】wandb The AI developer platform. Use Weights & Biases to train and fine-tune models, and manage models from experimentation to production. 项目地址: https://gitcode.com/gh_mirrors/wa/wandb 点… · 2026/9/23 18:08:48
wandb 开源贡献完全指南:从环境搭建、Conventional Commits 到自动化代码生成 wandb 开源贡献完全指南:从环境搭建、Conventional Commits 到自动化代码生成 【免费下载链接】wandb The AI developer platform. Use Weights & Biases to train and fine-tune models, and manage models from experimentation to production. 项目地址: h… · 2026/9/23 18:08:47
wandb 核心中的 Go 指数退避实现:jpillora/backoff 使用与源码剖析 机器学习深度学习数据可视化可观测性 【免费下载链接】wandb The AI developer platform. Use Weights & Biases to train and fine-tune models, and manage models from experimentation to production. 项目地址: https://gitcode.com/gh_mirrors/wa/wandb 点… · 2026/9/23 18:08:41
计算机软件工程避坑:从入门到精通的7个致命陷阱 计算机软件工程避坑:从入门到精通的7个致命陷阱 代码复制过来,编译全红,报错信息看得人想砸键盘。这种“明明逻辑对,但就是跑不通”的绝望感,是每一个从入门到精通路上的开发者都绕不开的坎。… · 2026/9/23 18:08:41
熊猫数据集双格式解析:VOC与YOLO坐标转换及训练校验全流程 简介:这是一份以熊猫为单一类别的目标检测数据集,面向计算机视觉初学者与算法工程师,可直接用于训练或验证Pascal VOC、YOLO两类常见检测模型。全部图像均已通过labelImg完成矩形框标注,类别标注为Panda,共114个真实框… · 2026/9/23 18:08:41
基于CNN与KDD Cup 99的机器学习入侵检测系统源码实战 简介:这是一套面向高校学生与初学者的机器学习入侵检测系统完整项目源码,适用于毕业设计、期末大作业与课程设计等场景,帮助读者快速搭建可运行的网络流量异常识别方案。压缩包共16个文件,约17.52MB,以py脚本、xml配置… · 2026/9/23 18:08:41
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29