withoutActuallyEscaping(_:do:)
聲明
func withoutActuallyEscaping<ClosureType, ResultType>(
_ closure: ClosureType,
do body: (ClosureType) throws -> ResultType
) rethrows -> ResultType
返回值
body
閉包的返回值(如果有)。
參數
closure
在
body
閉包執行期間可轉義的非轉義閉包值。如果body
有返回值,則該值也用作withoutActuallyEscaping(_:do:)
函數的返回值。body
使用
closure
的可逃避副本作為其參數立即執行的閉包。
詳述
您可以使用此函數調用一個 API,該 API 以一種不允許閉包在實踐中轉義的方式采用轉義閉包。下麵的示例演示了如何將 withoutActuallyEscaping(_:do:)
與使用轉義閉包的兩個常見 API 結合使用:惰性集合視圖和異步操作。
以下代碼聲明了一個 allValues(in:match:)
函數,用於檢查數組中的所有元素是否與謂詞匹配。該函數不會像編寫的那樣編譯,因為惰性集合的 filter(_:)
方法需要轉義閉包。惰性集合不會持久化,因此 predicate
閉包實際上不會轉義函數體;但是,它不能以這種方式使用。
func allValues(in array: [Int], match predicate: (Int) -> Bool) -> Bool {
return array.lazy.filter { !predicate($0) }.isEmpty
}
// error: closure use of non-escaping parameter 'predicate'...
withoutActuallyEscaping(_:do:)
提供了 predicate
的臨時可逃逸副本,can
可用於調用惰性視圖的 filter(_:)
方法。 allValues(in:match:)
的第二個版本編譯沒有錯誤,編譯器保證 escapablePredicate
閉包不會持續超過對 withoutActuallyEscaping(_:do:)
的調用。
func allValues(in array: [Int], match predicate: (Int) -> Bool) -> Bool {
return withoutActuallyEscaping(predicate) { escapablePredicate in
array.lazy.filter { !escapablePredicate($0) }.isEmpty
}
}
異步調用是另一種類型的 API,通常會轉義其閉包參數。以下代碼聲明了一個perform(_:simultaneouslyWith:)
函數,該函數使用調度隊列同時執行兩個閉包。
func perform(_ f: () -> Void, simultaneouslyWith g: () -> Void) {
let queue = DispatchQueue(label: "perform", attributes: .concurrent)
queue.async(execute: f)
queue.async(execute: g)
queue.sync(flags: .barrier) {}
}
// error: passing non-escaping parameter 'f'...
// error: passing non-escaping parameter 'g'...
perform(_:simultaneouslyWith:)
函數以使用.barrier
標誌調用sync(flags:execute:)
方法結束,這會強製函數等到兩個閉包都完成運行後再返回。盡管屏障保證兩個閉包都不會逃逸函數,但 async(execute:)
方法仍然要求傳遞的閉包標記為 @escaping
,因此函數的第一個版本無法編譯。要解決這些錯誤,您可以使用 withoutActuallyEscaping(_:do:)
獲取可以傳遞給 async(execute:)
的 f
和 g
的副本。
func perform(_ f: () -> Void, simultaneouslyWith g: () -> Void) {
withoutActuallyEscaping(f) { escapableF in
withoutActuallyEscaping(g) { escapableG in
let queue = DispatchQueue(label: "perform", attributes: .concurrent)
queue.async(execute: escapableF)
queue.async(execute: escapableG)
queue.sync(flags: .barrier) {}
}
}
}
可用版本
相關用法
- Swift withTaskGroup(of:returning:body:)用法及代碼示例
- Swift withThrowingTaskGroup(of:returning:body:)用法及代碼示例
- Swift KeyValuePairs flatMap(_:)用法及代碼示例
- Swift String.UTF8View first用法及代碼示例
- Swift Result.Publisher zip(_:_:_:)用法及代碼示例
- Swift Optional.Publisher reduce(_:_:)用法及代碼示例
- Swift Int8 ~(_:)用法及代碼示例
- Swift SetAlgebra isStrictSubset(of:)用法及代碼示例
- Swift UInt +(_:)用法及代碼示例
- Swift Array enumerated()用法及代碼示例
- Swift FlattenSequence prefix(_:)用法及代碼示例
- Swift Slice endIndex用法及代碼示例
- Swift LazySequence split(maxSplits:omittingEmptySubsequences:whereSeparator:)用法及代碼示例
- Swift MutableCollection partition(by:)用法及代碼示例
- Swift ReversedCollection min(by:)用法及代碼示例
- Swift RandomNumberGenerator用法及代碼示例
- Swift Dictionary.Keys shuffled()用法及代碼示例
- Swift AnySequence elementsEqual(_:)用法及代碼示例
- Swift UInt &<<(_:_:)用法及代碼示例
- Swift Optional.Publisher tryDrop(while:)用法及代碼示例
- Swift DefaultIndices endIndex用法及代碼示例
- Swift Substring.UnicodeScalarView insert(contentsOf:at:)用法及代碼示例
- Swift LazyFilterSequence dropFirst(_:)用法及代碼示例
- Swift LazySequence suffix(from:)用法及代碼示例
- Swift ArraySlice starts(with:)用法及代碼示例
注:本文由純淨天空篩選整理自apple.com大神的英文原創作品 withoutActuallyEscaping(_:do:)。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。