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

    View full-size slide

  2. ؛઒ࠀݾ @k_katsumi
    Apple ޷͖͕ߴͯ͡ iOS ΞϓϦέʔγϣ
    ϯͷ։ൃΛ 14 ೥ଓ͚͍ͯ·͢ɻझຯͰ
    ࡞͍ͬͯΔ OSS ϥΠϒϥϦ͸͚ͬ͜͏ਓ
    ؾ͕͋Γ·͢ɻ
    Yuta Koshizawa @koher
    "Heart of Swi-" Λॻ͖·ͨ͠ɻීஈ͸ओ
    ʹϦΞϧλΠϜը૾ॲཧΛ༻͍ͨ iOS Ξ
    ϓϦΛ։ൃ͍ͯ͠·͢ɻ

    View full-size slide

  3. Swi$ ͷ࠷৽ಈ޲

    View full-size slide

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

    View full-size slide

  5. Concurrency ʢฒߦॲཧʣ

    View full-size slide

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

    View full-size slide

  7. Ұݟ Ruby ΍ Python ͷΑ͏͚ͩͲɾɾɾ
    // 0 Ҏ্ 100 ະຬͷ੔਺ͷ߹ܭ
    var sum = 0
    for i in 0 ..< 100 {
    sum += i
    }
    print(sum)

    View full-size slide

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

    View full-size slide

  9. ίϯύΠϥ͕ΨνΨνʹ੩తݕࠪ͢Δݴޠ
    • Null Safety ʢ 2014 ೥ͷϦϦʔε౰ॳ͔Βʣ
    • throws/try ʢݕࠪྫ֎ͷΑ͏ͳ΋ͷʣ
    • σʔλڝ߹ͱσουϩοΫͷ๷ࢭ

    View full-size slide

  10. Swi$ ͷฒߦॲཧ
    !
    async/await
    "
    Structured Concurrency
    #
    actor

    View full-size slide

  11. !
    async/await

    View full-size slide

  12. async/await ͷྫ
    // Swift
    func fetchUser(...) async -> User {
    let userData = await downloadData(...)
    ...
    return user
    }
    Ұݟ JavaScript ౳ͷ async/await ͱࣅ͍ͯΔɻ

    View full-size slide

  13. JS/TS ͷ async/await ͱͷҧ͍
    // TypeScript
    async function fetchUser(...): Promise {
    const userData = await downloadData(...);
    ...
    return user;
    }
    JS/TS Ͱ͸ async ؔ਺͸ Promise Λฦ͢ɻ

    View full-size slide

  14. JS/TS ͷ async/await ͱͷҧ͍
    // Swift
    func fetchUser(...) async -> User {
    let userData = await downloadData(...)
    ...
    return user
    }
    Swi$ ͷ async ؔ਺͸ Promise Λฦ͞ͳ͍ɻ

    View full-size slide

  15. JS/TS ͷ async/await ͱͷҧ͍
    // TypeScript
    async function fetchUser(...): Promise {
    const promise = downloadData(...);
    ...
    return user;
    }
    JS/TS Ͱ͸ await ͠ͳ͍ͱ Promise ΛಘΔɻ

    View full-size slide

  16. JS/TS ͷ async/await ͱͷҧ͍
    // Swift
    func fetchUser(...) async -> User {
    let userData = downloadData(...) // ίϯύΠϧΤϥʔ
    ...
    return user
    }
    Swi$ Ͱ͸ await ͠ͳ͍ͱίϯύΠϧΤϥʔɻඞͣ await ͞ΕΔ
    ͷͰ Promise ʹ૬౰͢Δ΋ͷ͸ͳ͍ɻ

    View full-size slide

  17. await ඞਢͳͷͰ await ๨Ε͕ى͜Βͳ͍
    func updateUser(user: User) async {
    //

    ίϯύΠϧΤϥʔ
    db.collection("users")
    .document(user.id)
    .setData(from: user)
    }
    ʢಛʹ໭Γ஋͕ͳ͍৔߹Ͱ΋ʣҙਤͤͣ await Λ෇͚๨ΕΔࣄނ
    ͕ى͜Βͳ͍ɻ

    View full-size slide

  18. JS/TS Ͱ͸ Promise Λ׆༻ͯ͠ฒߦʹ࣮ߦ
    // TypeScript
    async function fetchUser(...): Promise {
    const userPromise = downloadData(...);
    const avatarPromise = downloadData(...);
    const [userData, avatarData]
    = await Promise.all([userPromise, avatarPromise]);
    ...
    return user;
    }
    await ͠ͳ͍͜ͱ͕Մೳͩͱෳ਺ͷඇಉظॲཧΛฒߦʹ࣮ߦͰ͖
    Δɻ

    View full-size slide

  19. await ඞਢͰ Promise ͕ͳ͍ͳΒෳ਺ͷ
    ඇಉظॲཧΛͲ͏΍ͬͯฒߦʹ࣮ߦ͢Δʁ

    View full-size slide

  20. !
    Structured Concurrency

    View full-size slide

  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
    }

    View full-size slide

  22. JS/TS ͷ৔߹
    // TypeScript
    async function fetchUser(...): Promise {
    const userPromise = downloadData(...);
    const avatarPromise = downloadData(...);
    const [userData, avatarData]
    = await Promise.all([userPromise, avatarPromise]);
    ...
    return user;
    }

    View full-size slide

  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 ͱҧͬͯείʔϓͷ֎ʹ࣋ͪग़ͤͳ͍ɻ

    View full-size slide

  24. Structured Concurrency
    ߏ଄Խϓϩάϥϛϯάʢ Structured Programming ʣͰ͸ goto Ͱ
    είʔϓ͔Β୤ग़Ͱ͖ͳ͍Α͏ʹɺ async let ͸ඞͣείʔϓ
    ͷதͰղܾ͞ΕΔɻ

    View full-size slide

  25. Structured Concurrency ͷԿ͕͏Ε͍͠ͷ͔?

    View full-size slide

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

    View full-size slide

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

    OKɹ
    }
    async ؔ਺͸ async ؔ਺ͷதͰ͔͠ݺ΂ͳ͍ɻ

    View full-size slide

  28. async ؔ਺ͷݺͼग़͠ͷ੍໿
    func foo() async -> Int { ... }
    func bar() -> Int {
    await foo() * 2 //

    ίϯύΠϧΤϥʔ
    }
    async ؔ਺͸ async ؔ਺ͷதͰ͔͠ݺ΂ͳ͍ɻ

    View full-size slide

  29. Task
    Task({
    await foo()
    })
    async ؔ਺ͷݺͼग़͠ͷେݩ͸ Task ͷίϯετϥΫλʢΠχ
    γϟϥΠβʣɻ͢΂ͯͷ async ؔ਺͸ Task ͷ্Ͱ࣮ߦ͞ΕΔɻ

    View full-size slide

  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 ͸πϦʔΛ࡞Δɻ

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. σʔλڝ߹ͷྫ
    class Counter {
    var count: Int = 0
    func increment() -> Int {
    count += 1
    return count
    }
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. Χ΢ϯλʹฒߦʹΞΫηε͢Δ৔߹
    let counter = Counter()
    Task {
    print(counter.increment()) // 2
    }
    Task {
    print(counter.increment()) // 2
    }
    ྆ํͷΠϯΫϦϝϯτ͕ߦΘΕͨޙͰ return ͞ΕΔͱ྆ऀͱ΋
    2 Λදࣔ͢Δɻ → σʔλڝ߹

    View full-size slide

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

    View full-size slide

  39. ैདྷͷղܾ๏: γϦΞϧΩϡʔ
    ΦϖϨʔγϣϯΛγϦΞϧΩϡʔʹೖΕͯɺΩϡʔ͕Ұͭͣͭॱ
    ൪ʹऔΓग़ͯ͠ॲཧΛ͢Δɻσʔλڝ߹΋σουϩοΫ΋ى͜Β
    ͳ͍ɻ

    View full-size slide

  40. ैདྷͷղܾ๏: γϦΞϧΩϡʔ
    class Counter {
    let queue = ...
    var count: Int = 0
    func increment(completion: (Int) -> Void) {
    queue.async {
    count += 1
    completion(count)
    }
    }
    }
    ࣮૷͕ෳࡶͩͬͨΓɺΩϡʔΛ࢖͏ͷΛ๨ΕͨΓ͕ͪ͠ɻ

    View full-size slide

  41. // γϦΞϧΩϡʔΛ࢖͏ݱ࣮ͷίʔυ͸ΑΓෳࡶ
    let queue = DispatchQueue(...)
    func load(_ url: URL) {
    queue.sync {
    // ϝϞϦΩϟογϡΛ୳͢
    ...
    }
    queue.sync {
    // σΟεΫΩϟογϡΛ୳͢
    ...
    }
    queue.async {
    // ը૾Λμ΢ϯϩʔυ
    fetch(url) {
    if {
    // ੒ޭ: Ωϟογϡʹอଘ
    // ίʔϧόοΫΛݺͿ
    ...
    } else if {
    // ηογϣϯ੾Ε:
    queue.async {
    // ϦϑϨογϡτʔΫϯͰϦτϥΠ
    }
    ...
    } else {
    // ࣦഊ: ΤϥʔϋϯυϥΛݺͿ
    ...
    }
    }
    }
    }

    View full-size slide

  42. actor ʹΑΔղܾ
    actor Counter {
    var count: Int = 0
    func increment() -> Int {
    count += 1
    return count
    }
    }
    ΩϡʔʹೖΕΔͷͱಉ͡Α͏ͳ͜ͱΛίϯύΠϥ͕ߦͬͯ͘Ε
    ΔɻύϑΥʔϚϯε΋ΑΓྑ͍ɻ

    View full-size slide

  43. actor ͷϝιουΛ֎͔ΒݟΔͱ
    actor Counter {
    ...
    func increment() async -> Int {
    ...
    }
    }
    actor ֎෦͔Β͸ async ϝιουʹݟ͑Δɻ

    View full-size slide

  44. actor ͷϝιουΛ֎͔ΒݟΔͱ
    let counter = Counter()
    print(await counter.increment())

    View full-size slide

  45. actor ͷϝιουΛத͔ΒݟΔͱ
    actor Counter {
    var count: Int = 0
    func countUp(amount: Int) -> Int {
    count += amount
    return count
    }
    func increment() -> Int {
    countUp(amount: 1) // ಉظݺͼग़͠
    }
    }
    ֎͔ΒݟͨΒ async ͚ͩͲɺத͔ΒݟͨΒಉظతɻ

    View full-size slide

  46. actor
    • ΦϖϨʔγϣϯΛΩϡʔʹೖΕͯॱ൪ʹߦ͏ͷͰσʔλڝ߹͕
    ى͜Βͳ͍
    • actor ͕ࣗಈతʹΦϖϨʔγϣϯΛΩϡʔʹೖΕΔͷͰΩϡʔ
    ʹೖΕ๨Εͳ͍
    • ֎෦͔Β͸ async ʹݟ͑ɺϒϩοΩϯά͕ଘࡏ͠ͳ͍ͷͰσο
    υϩοΫ͕ى͜Βͳ͍

    View full-size slide

  47. ͜Ε͚ͩͰ͸σʔλڝ߹Λ׬શʹ͸๷͛ͳ͍

    View full-size slide

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

    View full-size slide

  49. actor ʹ౉ͨ͠ΠϯελϯεΛ֎෦͔Βมߋ
    actor Foo {
    func method(x: X) { ... }
    }
    let foo = Foo()
    let x = X()
    foo.method(x: x) //

    ίϯύΠϧΤϥʔ
    x.value += 1
    ϛϡʔλϒϧΫϥεͷΠϯελϯεΛ౉͢ͱίϯύΠϧΤϥʔɻ
    ஋ܕ΍ΠϛϡʔλϒϧΫϥεͷΠϯελϯε͸౉ͤΔɻ

    View full-size slide

  50. actor ͔Βड͚औͬͨΠϯελϯεΛ֎෦͔Βมߋ
    actor Foo {
    let x = X()
    func method() -> X { return x }
    }
    let foo = Foo()
    let x = await foo.baz() //

    ίϯύΠϧΤϥʔ
    x.count += 1
    ϛϡʔλϒϧΫϥεͷΠϯελϯεΛฦ͢ͱίϯύΠϧΤϥʔɻ
    ஋ܕ΍ΠϛϡʔλϒϧΫϥεͷΠϯελϯε͸औΓग़ͤΔɻ

    View full-size slide

  51. ͦͷଞʹɺσουϩοΫΛ׬શʹ๷͙ͨΊʹ
    ͸ actor ͷ Reentrancy ͕ɾɾɾ
    ͕࣌ؒ଍Γͳ͍ͷͰৄࡉ͸ Proposal SE-0304 Λޚཡ͍ͩ͘͞ɻ
    SE-0304 Structured concurrency h)ps:/
    /github.com/apple/swi;-evolu=on/blob/main/proposals/0304-structured-
    concurrency.md

    View full-size slide

  52. ·ͱΊ
    !
    async/await
    "
    Structured Concurrency
    #
    actor
    ͜ΕΒͷ࢓૊ΈΛ༻͍ͯɺฒߦॲཧͰσʔλڝ߹ͱσουϩοΫ
    ͕ى͜Βͳ͍͜ͱΛίϯύΠϥ͕อূɻ

    View full-size slide

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

    View full-size slide