2023 Developer ToolsSwift
WWDC23 · 18 min · Developer Tools / Swift
Generalize APIs with parameter packs
Swift parameter packs are a powerful tool to expand what is possible in your generic code while also enabling you to simplify common generic patterns. We’ll show you how to abstract over types as well as the number of arguments in generic code and simplify common generic patterns to avoid overloads. To get the most out of this session, we recommend first checking out “Embrace Swift generics" from WWDC22.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 22 snippets
radians function
func radians(from degrees: Double) -> Double Array type
struct Array<Element> radians function and Array type with concrete expressions
func radians(from degrees: Double) -> Double
radians(from: 180)
struct Array<Element>
Array<Int> generic query
func query<Payload>(_ item: Request<Payload>) -> Payload variadic query
func query(_ item: Request...) generic query
func query<Payload>(_ item: Request<Payload>) -> Payload two query overloads
func query<Payload>(
_ item: Request<Payload>
) -> Payload
func query<Payload1, Payload2>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>
) -> (Payload1, Payload2) three query overloads
func query<Payload>(
_ item: Request<Payload>
) -> Payload
func query<Payload1, Payload2>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>
) -> (Payload1, Payload2)
func query<Payload1, Payload2, Payload3>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>,
_ item3: Request<Payload3>
) -> (Payload1, Payload2, Payload3) four query overloads with extra argument error
func query<Payload>(
_ item: Request<Payload>
) -> Payload
func query<Payload1, Payload2>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>
) -> (Payload1, Payload2)
func query<Payload1, Payload2, Payload3>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>,
_ item3: Request<Payload3>
) -> (Payload1, Payload2, Payload3)
func query<Payload1, Payload2, Payload3, Payload4>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>,
_ item3: Request<Payload3>,
_ item4: Request<Payload4>
) -> (Payload1, Payload2, Payload3, Payload4)
let _ = query(r1, r2, r3, r4, r5) for-in loop over requests
for request in requests {
evaluate(request)
} four query overloads
func query<Payload>(
_ item: Request<Payload>
) -> Payload
func query<Payload1, Payload2>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>
) -> (Payload1, Payload2)
func query<Payload1, Payload2, Payload3>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>,
_ item3: Request<Payload3>
) -> (Payload1, Payload2, Payload3)
func query<Payload1, Payload2, Payload3, Payload4>(
_ item1: Request<Payload1>,
_ item2: Request<Payload2>,
_ item3: Request<Payload3>,
_ item4: Request<Payload4>
) -> (Payload1, Payload2, Payload3, Payload4) parameter pack query interface
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload) parameter pack query with single argument call
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload)
let result = query(Request<Int>()) parameter pack query with single and triple argument calls
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload)
let result = query(Request<Int>())
let results = query(Request<Int>(), Request<String>(), Request<Bool>()) parameter pack query with triple argument call
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload)
let results = query(Request<Int>(), Request<String>(), Request<Bool>()) parameter pack query interface
func query<each Payload>(
_ item: repeat Request<each Payload>
) -> (repeat each Payload) parameter pack query interface with conformance
func query<each Payload: Equatable>(
_ item: repeat Request<each Payload>
) -> (repeat each Payload) parameter pack query interface with where clause
func query<each Payload>(
_ item: repeat Request<each Payload>
) -> (repeat each Payload)
where repeat each Payload: Equatable parameter pack query interface with minimum parameter count
func query<FirstPayload, each Payload>(
_ first: Request<FirstPayload>, _ item: repeat Request<each Payload>
) -> (FirstPayload, repeat each Payload)
where FirstPayload: Equatable, repeat each Payload: Equatable parameter pack query implementation
struct Request<Payload> {
func evaluate() -> Payload
}
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload) {
return (repeat (each item).evaluate())
} parameter pack query implementation with different input and output types
protocol RequestProtocol {
associatedtype Input
associatedtype Output
func evaluate(_ input: Input) -> Output
}
struct Evaluator<each Request: RequestProtocol> {
var item: (repeat each Request)
func query(_ input: repeat (each Request).Input) -> (repeat (each Request).Output) {
return (repeat (each item).evaluate(each input))
}
} parameter pack query implementation with control flow break
protocol RequestProtocol {
associatedtype Input
associatedtype Output
func evaluate(_ input: Input) throws -> Output
}
struct Evaluator<each Request: RequestProtocol> {
var item: (repeat each Request)
func query(_ input: repeat (each Request).Input) -> (repeat (each Request).Output)? {
do {
return (repeat try (each item).evaluate(each input))
} catch {
return nil
}
}
} Related sessions
-
43 min -
27 min -
26 min