You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非Sendable类C1用于Task<Success, Failure>为何可正常运行?

为什么非final类C1能被用作Task的Success类型?

先看你提供的代码片段:

class C1 {
    var i: Int
    init(i: Int) { self.i = i }
}
let t4 = Task<C1, Error>(operation: { return C1(i: 1) })
let v4: C1 = try await t4.value

结合Task的泛型约束Success : Sendable,以及Sendable对类的要求(需为final、存储属性不可变且符合Sendable等),C1明明不满足条件却能正常编译运行,核心原因在于Xcode的默认编译设置未开启严格并发检查。

编译设置的影响

在Xcode 14.1中,Strict Concurrency Checking(严格并发检查)的默认值为Minimal:

  • 该模式下,编译器仅对显式标注为Sendable的类型做基础验证,不会强制校验所有需要符合Sendable的场景(比如Task泛型参数的约束);
  • 若将此设置修改为Targeted或Complete,编译器会立即触发错误,明确提示C1不符合Sendable协议要求。

关于Sendable合规性的补充

虽然文档明确了类自动符合Sendable的条件,但还有两种手动声明方式(不推荐随意使用,会引入并发安全风险):

  • 直接添加协议声明:extension C1: Sendable {},编译器会跳过自动检查,依赖开发者自行保证类型的并发安全;
  • 使用@unchecked Sendable:extension C1: @unchecked Sendable {},明确告知编译器开发者已确认类型的并发安全性,完全绕过编译器检查。

你的代码并未使用这两种方式,本质是宽松的编译设置让代码“逃过”了检查,但这种写法存在隐患——C1的可变属性i可能在多任务环境下被同时修改,引发数据竞争问题。

内容的提问来源于stack exchange,提问作者Rainer Schwarze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:52:19