Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Function Builders in Swift 5.1

Function Builders in Swift 5.1

Christopher Rogers
WWDC19 Recap at LINE
https://line.connpass.com/event/134346/

LINE Developers

June 25, 2019
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

  1. Function Builder ͱ͸ʁ ؔ਺ΛϏϧμʔߏจʹมߋͰ͖Δ৽ػೳ1 • Embedded Domain-Specific Language (eDSL) •

    SwiftUI ͷͨΊʁ • GM·ͰมΘΔՄೳੑ͕ߴ͍ 1 https://forums.swift.org/t/function-builders/25167
  2. var body: some View { /* return লུ */ HStack

    { // ͔͜͜Β͕ function builder ߏจ Image(uiImage: profile.image) Spacer() Text(profile.name) } } public HStack { public init(@ViewBuilder _ content: () -> Content) }
  3. var body: some View { /* return লུ */ HStack

    { // ͔͜͜Β͕ function builder ߏจ Image(uiImage: profile.image) Spacer() Text(profile.name) } }
  4. var body: some View { /* return লུ */ HStack

    { // ͔͜͜Β͕ function builder ߏจ let _v0 = Image(uiImage: profile.image) let _v1 = Spacer() let _v2 = Text(profile.name) return ViewBuilder.buildBlock(_v0, _v1, _v2) } }
  5. • ܕΛఆٛ͢Δ • ܕͷએݴΛ @_functionBuilder Ͱम০͢Δ • ಛఆͷϝιουΛ࣮૷͢Δ • ४ڌ͢Δ

    protocol ͸ͳ͍ • ʢݱ࣌఺Ͱ͸ʣϝιου͸͢΂ͯ static • Ҿ਺ͱฦΓ஋ͷܕ͸͋Δఔ౓ࣗ༝ • ਂ͞༏ઌ୳ࡧͰࣜΛධՁͯ͠ม׵͍ͯ͘͠ @_functionBuilder public struct ViewBuilder { public static func buildBlock<Content>(_ content: Content) -> Content where Content: View }
  6. buildBlock • །Ұඞਢͷϝιου • จʢ{}Λ࢖ͬͨͱ͜Ζʣ୯ҐͰม׵͢Δ • ͢΂ͯͷࣜΛ·ͱΊͯҾ਺ͱͯ͠ड͚औΔ • ՄมҾ਺ •

    ϝιου overload Ͱෳ਺࣮૷ let _v0 = Image(uiImage: profile.image) let _v1 = Spacer() let _v2 = Text(profile.name) return ViewBuilder.buildBlock(_v0, _v1, _v2)
  7. buildExpression • ࣜ୯ҐͰม׵͢Δ͜ͱ͕Մೳ • ݱࡏ͸ར༻ෆՄ let _v0 = ViewBuilder.buildExpression(Image(uiImage: profile.image))

    let _v1 = ViewBuilder.buildExpression(Spacer()) let _v2 = ViewBuilder.buildExpression(Text(profile.name)) return ViewBuilder.buildBlock(_v0, _v1, _v2)
  8. var _v0Opt: String? var _v1Opt: Int? if isEnabled { _v0

    = "hoge" } else { _v1 = 42 } let _v0 = MyBuilder.buildOptional(_v0Opt) let _v1 = MyBuilder.buildOptional(_v1Opt)
  9. buildEither • ৚݅ʹΑΒͣܕΛ֬ఆ͢Δ͜ͱ͕Ͱ͖Δ • first/second ύϥϝʔλϥϕϧͰ෼ذ͕ද͞ΕΔ • ݱࡏ͸ར༻ෆՄ let _v0:

    String if languageCode == "ja" { _v0 = MyBuilder.buildEither(first: "hoge") } else if languageCode == "en" { _v0 = MyBuilder.buildEither(second: MyBuilder.buildEither(first: "foo")) } else { _v0 = MyBuilder.buildEither(second: MyBuilder.buildEither(second: "")) }