Save 37% off PRO during our Black Friday Sale! »

Swift Language Updates - Learn Languages 2021

Swift Language Updates - Learn Languages 2021

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

3c031541ed3d92869414857dfef853de?s=128

Yuta Koshizawa

August 28, 2021
Tweet

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