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

Transcript

57 slides
  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

More Decks by Yuta Koshizawa

Other Decks in Programming