🫀
Swift5.10 新機能: 厳密な並行処理チェック
次のコードをターミナル上でコンパイルする。
strict.swift
var v = 1
// nonisolated(unsafe) var v = 1
func f() {
v = 2
}
f()
print(v) // => 2
コンパイル・オプションは次の通り
$ swift -strict-concurrency=complete strict.swift
strict.swift:4:3: error: main actor-isolated var 'v' can not be mutated from a non-isolated context
v = 2
^
strict.swift:1:5: note: mutation of this var is only permitted within the actor
var v = 1
^
strict.swift:3:6: note: add '@MainActor' to make global function 'f()' part of global actor 'MainActor'
func f() {
^
@MainActor
データ競合により意図しない値の変更に悩まされた時に、原因調査の手段として以前からコンパイラ・オプション-strict-concurrency=complete
は有った。このオプションはコードを部分的に調査するものだったのが、5.10からすべての安全でないコードにコンパイルエラーを発する様になった。
今回のコードの場合コンパイルエラーを取り除くには次の手段がある
1. 変数vへの同時アクセスするコードは無いので原因調査の対象から外す。つまりnonisolated(unsafe) var v = 1
とコードを書き換えれば良い
2. 変数vを書き換える処理を含むf()を相互排他制御(Mutex, Mutual Exclusion)の対象とする。つまり@MainActor func f()...
とコードを書き換える。排他制御は計算コストの増大を招く。本当に必要でない場合はコードの書き換えを避ける
3. コンパイラ・オプションを取る
環境
$ sw_vers
ProductName: macOS
ProductVersion: 14.4.1
BuildVersion: 23E224
$ swift -v
Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
swift-evolution/proposals/0412-strict-concurrency-for-global-variables.md at main · apple/swift-evolution
Swift 6 に備える - 今後の機能(Upcoming Feature)の段階的適用 編
Discussion