在Swift 6中,将默认的Actor隔离设为主Actor之后,出现了与协议符合性相关的异常行为

移动开发 2026-07-09

我有这段代码:

protocol MainP {
  func foo()
}

nonisolated protocol NonIsoP {
  func bar()
}

struct MainStruct1: MainP {
  func foo() {}
}

struct MainStruct2: NonIsoP {
  func bar() {}
}

nonisolated struct NonIsoStruct1: MainP {
  func foo() {}
}

nonisolated struct NonIsoStruct2: MainP {
  @MainActor
  func foo() {}
}

nonisolated struct NonIsoStruct3: NonIsoP {
  func bar() {}
}

nonisolated struct NonIsoStruct4: NonIsoP {
  @MainActor
  func bar() {}
}

我创建了一个新项目(我使用Xcode 26.2),把设置改为:

  1. 默认的actor隔离设为main actor
  2. Swift语言 = Swift 6

然后只有 NonIsoStruct4 会报错。

对协议 'NonIsoP' 的 'NonIsoStruct4' 的符合性跨入了主actor隔离代码,可能导致数据竞争

然而,我预计 MainStruct2 会因为同样的错误而失败,因为MainStruct2不满足 NonIsoP 的“拥有非隔离foo()”的要求。本来它应该和以下编译错误完全一致:错误“Conformance of [StructType] to protocol [ProtocolType] crosses into main actor isolated code in approachable concurrency”,但不知为何现在就通过了。

解决方案

这在这里有文档:在这里:

SE-0466提供了指定给定模块将对任何未显式声明隔离(或非隔离,通过 nonisolated)的代码推断 @MainActor 的能力。在一个推断 @MainActor 的模块中,来自前一节的即将到来的特性 InferIsolatedConformances 也应被启用。这意味着类型将获得主actor的隔离,并且它们的符合性也将是主actor隔离的,将SE-0466的“主要是单线程”的观点扩展到与通用代码的交互。

所以实际上 MainStruct2 是隐式的一个隔离符合:

@MainActor
struct MainStruct2: @MainActor NonIsoP {
  func bar() {}
}

这与 RLActionState 之间唯一的区别在于 RLActionState 已经是主actor隔离,因此我猜编译器只会忽略它,不会将其视为一个隔离的符合,同时也没有考虑它继承自 CustomDebugStringConvertible 的事实。

这个问题似乎已经在这里被报道过:在这里。请关注该问题以获取更多更新。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章