我有這兩個函式(編譯時沒有錯誤):
func hasLocalChanges() -> Bool {
return false
}
func hasRemoteChanges() async -> Bool {
return await Task{ true }.value
}
現在,假設我想引入第三個函式,如下所示:
func hasChanges() async -> Bool {
return self.hasLocalChanges() || await self.hasRemoteChanges()
}
然后這個函式會給我一個編譯器錯誤說:
'async' call in an autoclosure that does not support concurrency
但這是為什么呢?
我可以通過交換運算元來解決錯誤……
func hasChanges() async -> Bool {
return await self.hasRemoteChanges() || self.hasLocalChanges()
}
…,這又一次可以使代碼編譯時沒有錯誤。
但我真的很想利用惰性求值并讓異步函式最后執行。因此,實作這一目標的唯一方法就是說……
func hasChanges() async -> Bool {
if !self.hasLocalChanges() {
return await self.hasRemoteChanges()
} else {
return true
}
}
......,這似乎有點麻煩。
誰能向我解釋為什么我首先會遇到這個錯誤?
編輯:
非常感謝@aciniglio:
重寫代碼的一種方法是這樣的(假設兩個函式也被允許拋出):
func hasChanges() async throws -> Bool {
return try await hasLocalChanges().or(await hasRemoteChanges())
}
extension Bool {
func or(_ other: @autoclosure () async throws -> Bool) async rethrows -> Bool {
return self ? true : try await other()
}
}
uj5u.com熱心網友回復:
這是因為||實際上是一個希望右手邊看起來像的函式rhs: @autoclosure () throws -> Bool(與 eg 相比rhs: @autoclosure () async throws -> Bool)
在此處查看源代碼:https ://github.com/apple/swift/blob/e6cbf5483237aa593bdbafb6c7db7ebcb2d0e26a/stdlib/public/core/Bool.swift#L320
當您首先移動等待時,它會決議為布林值,然后self.hasLocalChanges()是非異步的() throws -> Bool
下面編譯的示例
func hasChanges() async -> Bool {
return or( a: await hasRemoteChanges(), b: hasLocalChanges())
}
// This is pretty much what `||` looks like today
func or(a: Bool, b: @autoclosure () throws -> Bool) -> Bool {
return a ? true : try b()
}
func hasChanges() async -> Bool {
return await or( a: hasLocalChanges(), b: await hasRemoteChanges())
}
// This is what an `async` friendly `||` could look like.
// Note that the caller would need to await the result.
func or(a: Bool, b: @autoclosure () async throws -> Bool) async -> Bool {
return a ? true : try! await b()
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/491674.html
