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

Swift Language Updates - Learn Languages 2021

Swift Language Updates - Learn Languages 2021

Swift 5.5 の目玉は Concurrency (並行処理)関連の言語機能の追加です。 Swift 5.5 には Concurrency 以外にも細々としたアップデートはありますが、本トークでは Concurrency にフォーカスして紹介します。

Yuta Koshizawa

August 28, 2021
Tweet

More Decks by Yuta Koshizawa

Other Decks in Programming

Transcript

  1. ؛઒ࠀݾ @k_katsumi Apple ޷͖͕ߴͯ͡ iOS ΞϓϦέʔγϣ ϯͷ։ൃΛ 14 ೥ଓ͚͍ͯ·͢ɻझຯͰ ࡞͍ͬͯΔ

    OSS ϥΠϒϥϦ͸͚ͬ͜͏ਓ ؾ͕͋Γ·͢ɻ Yuta Koshizawa @koher "Heart of Swi-" Λॻ͖·ͨ͠ɻීஈ͸ओ ʹϦΞϧλΠϜը૾ॲཧΛ༻͍ͨ iOS Ξ ϓϦΛ։ൃ͍ͯ͠·͢ɻ
  2. Ұݟ Ruby ΍ Python ͷΑ͏͚ͩͲɾɾɾ // 0 Ҏ্ 100 ະຬͷ੔਺ͷ߹ܭ

    var sum = 0 for i in 0 ..< 100 { sum += i } print(sum)
  3. async/await ͷྫ // Swift func fetchUser(...) async -> User {

    let userData = await downloadData(...) ... return user } Ұݟ JavaScript ౳ͷ async/await ͱࣅ͍ͯΔɻ
  4. JS/TS ͷ async/await ͱͷҧ͍ // TypeScript async function fetchUser(...): Promise<User>

    { const userData = await downloadData(...); ... return user; } JS/TS Ͱ͸ async ؔ਺͸ Promise Λฦ͢ɻ
  5. JS/TS ͷ async/await ͱͷҧ͍ // Swift func fetchUser(...) async ->

    User { let userData = await downloadData(...) ... return user } Swi$ ͷ async ؔ਺͸ Promise Λฦ͞ͳ͍ɻ
  6. JS/TS ͷ async/await ͱͷҧ͍ // TypeScript async function fetchUser(...): Promise<User>

    { const promise = downloadData(...); ... return user; } JS/TS Ͱ͸ await ͠ͳ͍ͱ Promise ΛಘΔɻ
  7. JS/TS ͷ async/await ͱͷҧ͍ // Swift func fetchUser(...) async ->

    User { let userData = downloadData(...) // ίϯύΠϧΤϥʔ ... return user } Swi$ Ͱ͸ await ͠ͳ͍ͱίϯύΠϧΤϥʔɻඞͣ await ͞ΕΔ ͷͰ Promise ʹ૬౰͢Δ΋ͷ͸ͳ͍ɻ
  8. await ඞਢͳͷͰ await ๨Ε͕ى͜Βͳ͍ func updateUser(user: User) async { //

    ⛔ ίϯύΠϧΤϥʔ db.collection("users") .document(user.id) .setData(from: user) } ʢಛʹ໭Γ஋͕ͳ͍৔߹Ͱ΋ʣҙਤͤͣ await Λ෇͚๨ΕΔࣄނ ͕ى͜Βͳ͍ɻ
  9. JS/TS Ͱ͸ Promise Λ׆༻ͯ͠ฒߦʹ࣮ߦ // TypeScript async function fetchUser(...): Promise<User>

    { const userPromise = downloadData(...); const avatarPromise = downloadData(...); const [userData, avatarData] = await Promise.all([userPromise, avatarPromise]); ... return user; } await ͠ͳ͍͜ͱ͕Մೳͩͱෳ਺ͷඇಉظॲཧΛฒߦʹ࣮ߦͰ͖ Δɻ
  10. async let Ͱฒߦॲཧ // Swift func fetchUser(...) async -> User

    { async let userData = downloadData(...) async let avatarData = downloadData(...) let user = await User(data: userData, avatar: avatarData) return user }
  11. JS/TS ͷ৔߹ // TypeScript async function fetchUser(...): Promise<User> { const

    userPromise = downloadData(...); const avatarPromise = downloadData(...); const [userData, avatarData] = await Promise.all([userPromise, avatarPromise]); ... return user; }
  12. async let Ͱฒߦॲཧ // Swift func fetchUser(...) async -> User

    { async let userData = downloadData(...) async let avatarData = downloadData(...) let user = await User(data: userData, avatar: avatarData) return user } async let ͸ Promise ͱҧͬͯείʔϓͷ֎ʹ࣋ͪग़ͤͳ͍ɻ
  13. async ؔ਺ͷݺͼग़͠ͷ੍໿ func foo() async -> Int { ... }

    func bar() async -> Int { await foo() * 2 // ✅ OKɹ } async ؔ਺͸ async ؔ਺ͷதͰ͔͠ݺ΂ͳ͍ɻ
  14. async ؔ਺ͷݺͼग़͠ͷ੍໿ func foo() async -> Int { ... }

    func bar() -> Int { await foo() * 2 // ⛔ ίϯύΠϧΤϥʔ } async ؔ਺͸ async ؔ਺ͷதͰ͔͠ݺ΂ͳ͍ɻ
  15. Child Task Task({ async let a = foo() // Child

    Task: foo async let b = bar() // Child Task: bar print(await a + b) }) async let Ͱ͸ฒߦʹ࣮ߦ͞ΕΔ Child Task ͕࡞ΒΕΔɻߏ଄Խ ͞Ε͍ͯΔͷͰ Task ͸πϦʔΛ࡞Δɻ
  16. ඇಉظॲཧͷΩϟϯηϧ let task = Task({ async let a = foo()

    async let b = bar() print(try await a + b) }) task.cancel() Task Λ cancel ͢Δͱ Task πϦʔશମ͕ҰׅΩϟϯηϧ͞Ε ΔɻඇಉظॲཧͷΩϟϯηϧΛѻ͍΍͍͢ɻ
  17. σʔλڝ߹ͷྫ class Counter { var count: Int = 0 func

    increment() -> Int { count += 1 return count } }
  18. Χ΢ϯλʹฒߦʹΞΫηε͢Δ৔߹ let counter = Counter() Task { print(counter.increment()) // 2

    } Task { print(counter.increment()) // 2 } ྆ํͷΠϯΫϦϝϯτ͕ߦΘΕͨޙͰ return ͞ΕΔͱ྆ऀͱ΋ 2 Λදࣔ͢Δɻ → σʔλڝ߹
  19. ैདྷͷղܾ๏: ϩοΫ class Counter { var count: Int = 0

    func increment() -> Int { lock() defer { unlock() } count += 1 return count } } ϩοΫΛ࢖͏ͱεϨουΛϒϩοΫͯ͠͠·͏ύϑΥʔϚϯε্ ͷෆརӹʹՃ͑ͯɺσουϩοΫͷݪҼͱͳΔڪΕ͕͋Δɻ
  20. ैདྷͷղܾ๏: γϦΞϧΩϡʔ class Counter { let queue = ... var

    count: Int = 0 func increment(completion: (Int) -> Void) { queue.async { count += 1 completion(count) } } } ࣮૷͕ෳࡶͩͬͨΓɺΩϡʔΛ࢖͏ͷΛ๨ΕͨΓ͕ͪ͠ɻ
  21. // γϦΞϧΩϡʔΛ࢖͏ݱ࣮ͷίʔυ͸ΑΓෳࡶ let queue = DispatchQueue(...) func load(_ url: URL)

    { queue.sync { // ϝϞϦΩϟογϡΛ୳͢ ... } queue.sync { // σΟεΫΩϟογϡΛ୳͢ ... } queue.async { // ը૾Λμ΢ϯϩʔυ fetch(url) { if { // ੒ޭ: Ωϟογϡʹอଘ // ίʔϧόοΫΛݺͿ ... } else if { // ηογϣϯ੾Ε: queue.async { // ϦϑϨογϡτʔΫϯͰϦτϥΠ } ... } else { // ࣦഊ: ΤϥʔϋϯυϥΛݺͿ ... } } } }
  22. actor ʹΑΔղܾ actor Counter { var count: Int = 0

    func increment() -> Int { count += 1 return count } } ΩϡʔʹೖΕΔͷͱಉ͡Α͏ͳ͜ͱΛίϯύΠϥ͕ߦͬͯ͘Ε ΔɻύϑΥʔϚϯε΋ΑΓྑ͍ɻ
  23. actor ͷϝιουΛ֎͔ΒݟΔͱ actor Counter { ... func increment() async ->

    Int { ... } } actor ֎෦͔Β͸ async ϝιουʹݟ͑Δɻ
  24. actor ͷϝιουΛத͔ΒݟΔͱ actor Counter { var count: Int = 0

    func countUp(amount: Int) -> Int { count += amount return count } func increment() -> Int { countUp(amount: 1) // ಉظݺͼग़͠ } } ֎͔ΒݟͨΒ async ͚ͩͲɺத͔ΒݟͨΒಉظతɻ
  25. actor ʹ౉ͨ͠ΠϯελϯεΛ֎෦͔Βมߋ actor Foo { func method(x: X) { ...

    } } let foo = Foo() let x = X() foo.method(x: x) x.value += 1 // कΒΕ͍ͯͳ͍
  26. actor ʹ౉ͨ͠ΠϯελϯεΛ֎෦͔Βมߋ actor Foo { func method(x: X) { ...

    } } let foo = Foo() let x = X() foo.method(x: x) // ⛔ ίϯύΠϧΤϥʔ x.value += 1 ϛϡʔλϒϧΫϥεͷΠϯελϯεΛ౉͢ͱίϯύΠϧΤϥʔɻ ஋ܕ΍ΠϛϡʔλϒϧΫϥεͷΠϯελϯε͸౉ͤΔɻ
  27. actor ͔Βड͚औͬͨΠϯελϯεΛ֎෦͔Βมߋ actor Foo { let x = X() func

    method() -> X { return x } } let foo = Foo() let x = await foo.baz() // ⛔ ίϯύΠϧΤϥʔ x.count += 1 ϛϡʔλϒϧΫϥεͷΠϯελϯεΛฦ͢ͱίϯύΠϧΤϥʔɻ ஋ܕ΍ΠϛϡʔλϒϧΫϥεͷΠϯελϯε͸औΓग़ͤΔɻ
  28. ͦͷଞʹɺσουϩοΫΛ׬શʹ๷͙ͨΊʹ ͸ actor ͷ Reentrancy ͕ɾɾɾ ͕࣌ؒ଍Γͳ͍ͷͰৄࡉ͸ Proposal SE-0304 Λޚཡ͍ͩ͘͞ɻ

    SE-0304 Structured concurrency h)ps:/ /github.com/apple/swi;-evolu=on/blob/main/proposals/0304-structured- concurrency.md
  29. ࢀߟจݙ 10254 Swi$ concurrency: Behind the scenes h(ps:/ /developer.apple.com/videos/play/wwdc2021/10254/ 10134

    Explore structured concurrency in Swi3 h'ps:/ /developer.apple.com/videos/play/wwdc2021/10134/ 10133 Protect mutable state with Swi2 actors h&ps:/ /developer.apple.com/videos/play/wwdc2021/10133/ 10132 Meet async/await in Swi. h'ps:/ /developer.apple.com/videos/play/wwdc2021/10132/ WWDC 2021 Sessions SE-0317 async let bindings h*ps:/ /github.com/apple/swi<-evolu>on/blob/main/proposals/0317-async-let.md SE-0316 Global actors h*ps:/ /github.com/apple/swi<-evolu>on/blob/main/proposals/0316-global-actors.md SE-0306 Actors h)ps:/ /github.com/apple/swi;-evolu=on/blob/main/proposals/0306-actors.md SE-0304 Structured concurrency h)ps:/ /github.com/apple/swi;-evolu=on/blob/main/proposals/0304-structured- concurrency.md SE-0302 Sendable and @Sendable closures h)ps:/ /github.com/apple/swi;-evolu=on/blob/main/proposals/0302- concurrent-value-and-concurrent-closures.md SE-0296 Async/await h*ps:/ /github.com/apple/swi<-evolu>on/blob/main/proposals/0296-async-await.md Swi$ Evolu+on Proposals