Swift 中的 `nonisolated` 关键字是什么?

What is the `nonisolated` keyword in Swift?

我最近在下面的代码中遇到 Swift 中的 nonisolated 关键字:

actor BankAccount {

    init(balance: Double) {
        self.balance = balance
    }

    private var balance: Double

    nonisolated func availableCountries() -> [String] {
        return ["US", "CA", "NL"]
    }

    func increaseBalance(by amount: Double) {
        self.balance += amount
    }

}

它有什么作用?代码在有和没有它的情况下都能编译。

SE-313 中引入了 nonisolated 关键字。它用于向编译器指示方法内的代码未访问(读取或写入)actor 内的任何可变状态。这反过来又使我们能够从 non-async 上下文中调用该方法。

availableCountries() 方法可以nonisolated 因为它不依赖于 actor 内部的任何可变状态(例如,它不依赖于 balance 变量).

当您从 actor 外部访问 actor 的不同方法或变量时,您只能从异步上下文内部执行此操作。

让我们从 availableCountries() 方法中删除 nonisolated 关键字。现在,如果我们想使用该方法,我们只能在异步上下文中这样做。例如,在 Task:

let bankAccount = BankAccount(balance: 1000)

override func viewDidLoad() {
    super.viewDidLoad()

    Task {

        let availableCountries = await bankAccount.availableCountries()
        print(availableCountries)

    }

}

如果我们尝试在异步上下文之外使用该方法,编译器会报错:

但是,availableCountries() 没有使用 actor 的任何可变状态。因此,我们可以使它成为 nonisolated,然后我们才能从非异步上下文中调用它(编译器不会唠叨)。