Swift 6中非Sendable类型隐式转为Sendable无报错问题咨询
Swift 6中Sendable闭包传入接受Any参数的函数为何编译正常?
前置代码定义
struct MySendableType: Sendable { init() {} } class MyNonSendableType { init() {} } func takesSendableParam(closure: (Sendable) -> Void) { closure(MySendableType()) } func takesNonSendableParam(closure: (Any) -> Void) { closure(MyNonSendableType()) }
实验闭包定义
func experiment() { let sendable: (Sendable) -> Void = { data in // 因类型为Sendable,可自由跨线程传递数据 Task { @MainActor in DispatchQueue.global().async { print(data) DispatchQueue.main.async { print(data) } } print(data) } } let nonSendable: (Any) -> Void = { data in // 因类型非Sendable,无法跨线程传递数据 } // ... }
不符合预期的编译现象
补充调用代码后,出现了与预期不符的情况:
func experiment() { let sendable = ... let nonSendable = ... // (1) 编译正常,符合预期 takesSendableParam(closure: nonSendable) // (2) 为何编译正常??? takesNonSendableParam(closure: sendable) }
问题核心
对于(2),预期是编译失败:takesNonSendableParam会将MyNonSendableType实例传入sendable闭包,而该闭包内部会跨线程传递这个非Sendable类型,这违反了Swift 6的并发安全规则。但实际编译正常,且已确认启用Swift 6模式,求解释该现象的原因。
完整代码
struct MySendableType: Sendable { init() {} } class MyNonSendableType { init() {} } func takesSendableParam(closure: (Sendable) -> Void) { closure(MySendableType()) } func takesNonSendableParam(closure: (Any) -> Void) { closure(MyNonSendableType()) } func experiment() { let sendable: (Sendable) -> Void = { data in // 因类型为Sendable,可自由传递数据 Task { @MainActor in DispatchQueue.global().async { print(data) DispatchQueue.main.async { print(data) } } print(data) } } let nonSendable: (Any) -> Void = { data in } takesSendableParam(closure: nonSendable) // 为何编译正常??? takesNonSendableParam(closure: sendable) }
内容的提问来源于stack exchange,提问作者HL666
相关产品推荐
相关产品推荐

