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. Swi$ ؛઒ࠀݾ @k_katsumi Yuta Koshizawa @koher

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

    OSS ϥΠϒϥϦ͸͚ͬ͜͏ਓ ؾ͕͋Γ·͢ɻ Yuta Koshizawa @koher "Heart of Swi-" Λॻ͖·ͨ͠ɻීஈ͸ओ ʹϦΞϧλΠϜը૾ॲཧΛ༻͍ͨ iOS Ξ ϓϦΛ։ൃ͍ͯ͠·͢ɻ
  3. Swi$ ͷ࠷৽ಈ޲

  4. Swi$ 5.5: 9 ݄ϦϦʔεʢʁʣ

  5. Concurrency ʢฒߦॲཧʣ

  6. Swi$ 5.5+ ͷ Concurrency ฒߦॲཧʹىҼ͢Δσʔλڝ߹΍σουϩοΫ͕ى͜Βͳ͍͜ͱ ΛίϯύΠϥ͕อূͯ͘͠ΕΔɻ

  7. Ұݟ Ruby ΍ Python ͷΑ͏͚ͩͲɾɾɾ // 0 Ҏ্ 100 ະຬͷ੔਺ͷ߹ܭ

    var sum = 0 for i in 0 ..< 100 { sum += i } print(sum)
  8. ίϯύΠϥ͕ΨνΨνʹ੩తݕࠪ͢Δݴޠ • Null Safety ʢ 2014 ೥ͷϦϦʔε౰ॳ͔Βʣ • throws/try ʢݕࠪྫ֎ͷΑ͏ͳ΋ͷʣ

  9. ίϯύΠϥ͕ΨνΨνʹ੩తݕࠪ͢Δݴޠ • Null Safety ʢ 2014 ೥ͷϦϦʔε౰ॳ͔Βʣ • throws/try ʢݕࠪྫ֎ͷΑ͏ͳ΋ͷʣ

    • σʔλڝ߹ͱσουϩοΫͷ๷ࢭ
  10. Swi$ ͷฒߦॲཧ ! async/await " Structured Concurrency # actor

  11. ! async/await

  12. async/await ͷྫ // Swift func fetchUser(...) async -> User {

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

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

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

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

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

    ⛔ ίϯύΠϧΤϥʔ db.collection("users") .document(user.id) .setData(from: user) } ʢಛʹ໭Γ஋͕ͳ͍৔߹Ͱ΋ʣҙਤͤͣ await Λ෇͚๨ΕΔࣄނ ͕ى͜Βͳ͍ɻ
  18. 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 ͠ͳ͍͜ͱ͕Մೳͩͱෳ਺ͷඇಉظॲཧΛฒߦʹ࣮ߦͰ͖ Δɻ
  19. await ඞਢͰ Promise ͕ͳ͍ͳΒෳ਺ͷ ඇಉظॲཧΛͲ͏΍ͬͯฒߦʹ࣮ߦ͢Δʁ

  20. ! Structured Concurrency

  21. 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 }
  22. JS/TS ͷ৔߹ // TypeScript async function fetchUser(...): Promise<User> { const

    userPromise = downloadData(...); const avatarPromise = downloadData(...); const [userData, avatarData] = await Promise.all([userPromise, avatarPromise]); ... return user; }
  23. 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 ͱҧͬͯείʔϓͷ֎ʹ࣋ͪग़ͤͳ͍ɻ
  24. Structured Concurrency ߏ଄Խϓϩάϥϛϯάʢ Structured Programming ʣͰ͸ goto Ͱ είʔϓ͔Β୤ग़Ͱ͖ͳ͍Α͏ʹɺ async

    let ͸ඞͣείʔϓ ͷதͰղܾ͞ΕΔɻ
  25. Structured Concurrency ͷԿ͕͏Ε͍͠ͷ͔?

  26. ྫ: ඇಉظॲཧͷΩϟϯηϧ

  27. async ؔ਺ͷݺͼग़͠ͷ੍໿ func foo() async -> Int { ... }

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

    func bar() -> Int { await foo() * 2 // ⛔ ίϯύΠϧΤϥʔ } async ؔ਺͸ async ؔ਺ͷதͰ͔͠ݺ΂ͳ͍ɻ
  29. Task Task({ await foo() }) async ؔ਺ͷݺͼग़͠ͷେݩ͸ Task ͷίϯετϥΫλʢΠχ γϟϥΠβʣɻ͢΂ͯͷ

    async ؔ਺͸ Task ͷ্Ͱ࣮ߦ͞ΕΔɻ
  30. 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 ͸πϦʔΛ࡞Δɻ
  31. None
  32. None
  33. ඇಉظॲཧͷΩϟϯηϧ let task = Task({ async let a = foo()

    async let b = bar() print(try await a + b) }) task.cancel() Task Λ cancel ͢Δͱ Task πϦʔશମ͕ҰׅΩϟϯηϧ͞Ε ΔɻඇಉظॲཧͷΩϟϯηϧΛѻ͍΍͍͢ɻ
  34. ! actor

  35. σʔλڝ߹ͱσουϩοΫͷ๷ࢭ

  36. σʔλڝ߹ͷྫ class Counter { var count: Int = 0 func

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

    } Task { print(counter.increment()) // ? }
  38. Χ΢ϯλʹฒߦʹΞΫηε͢Δ৔߹ let counter = Counter() Task { print(counter.increment()) // 1

    } Task { print(counter.increment()) // 2 }
  39. Χ΢ϯλʹฒߦʹΞΫηε͢Δ৔߹ let counter = Counter() Task { print(counter.increment()) // 2

    } Task { print(counter.increment()) // 1 }
  40. Χ΢ϯλʹฒߦʹΞΫηε͢Δ৔߹ let counter = Counter() Task { print(counter.increment()) // 2

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

    func increment() -> Int { lock() defer { unlock() } count += 1 return count } } ϩοΫΛ࢖͏ͱεϨουΛϒϩοΫͯ͠͠·͏ύϑΥʔϚϯε্ ͷෆརӹʹՃ͑ͯɺσουϩοΫͷݪҼͱͳΔڪΕ͕͋Δɻ
  42. ैདྷͷղܾ๏: γϦΞϧΩϡʔ ΦϖϨʔγϣϯΛγϦΞϧΩϡʔʹೖΕͯɺΩϡʔ͕Ұͭͣͭॱ ൪ʹऔΓग़ͯ͠ॲཧΛ͢Δɻσʔλڝ߹΋σουϩοΫ΋ى͜Β ͳ͍ɻ

  43. None
  44. ैདྷͷղܾ๏: γϦΞϧΩϡʔ class Counter { let queue = ... var

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

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

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

    Int { ... } } actor ֎෦͔Β͸ async ϝιουʹݟ͑Δɻ
  48. actor ͷϝιουΛ֎͔ΒݟΔͱ let counter = Counter() print(await counter.increment())

  49. actor ͷϝιουΛத͔ΒݟΔͱ actor Counter { var count: Int = 0

    func countUp(amount: Int) -> Int { count += amount return count } func increment() -> Int { countUp(amount: 1) // ಉظݺͼग़͠ } } ֎͔ΒݟͨΒ async ͚ͩͲɺத͔ΒݟͨΒಉظతɻ
  50. actor • ΦϖϨʔγϣϯΛΩϡʔʹೖΕͯॱ൪ʹߦ͏ͷͰσʔλڝ߹͕ ى͜Βͳ͍ • actor ͕ࣗಈతʹΦϖϨʔγϣϯΛΩϡʔʹೖΕΔͷͰΩϡʔ ʹೖΕ๨Εͳ͍ • ֎෦͔Β͸

    async ʹݟ͑ɺϒϩοΩϯά͕ଘࡏ͠ͳ͍ͷͰσο υϩοΫ͕ى͜Βͳ͍
  51. ͜Ε͚ͩͰ͸σʔλڝ߹Λ׬શʹ͸๷͛ͳ͍

  52. actor ʹ౉ͨ͠ΠϯελϯεΛ֎෦͔Βมߋ actor Foo { func method(x: X) { ...

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

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

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

    SE-0304 Structured concurrency h)ps:/ /github.com/apple/swi;-evolu=on/blob/main/proposals/0304-structured- concurrency.md
  56. ·ͱΊ ! async/await " Structured Concurrency # actor ͜ΕΒͷ࢓૊ΈΛ༻͍ͯɺฒߦॲཧͰσʔλڝ߹ͱσουϩοΫ ͕ى͜Βͳ͍͜ͱΛίϯύΠϥ͕อূɻ

  57. ࢀߟจݙ 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