Kotlin と比較して理解する Swift 5 で実装されるかもしれない async/await について

7d1521d950d9bc5697868830cb04ff2f?s=47 yimajo
July 26, 2018

Kotlin と比較して理解する Swift 5 で実装されるかもしれない async/await について

potatotips #53 (iOS/Android開発Tips共有会) in マネーフォワード社で発表した資料です。

7d1521d950d9bc5697868830cb04ff2f?s=128

yimajo

July 26, 2018
Tweet

Transcript

  1. Kotlin ͱൺֱͯ͠ཧղ͢Δ Swift 5 Ͱ࣮૷͞ΕΔ͔΋͠Εͳ͍ async/await ʹ͍ͭͯ גࣜձࣾΩϡϦΦγςΟιϑτ΢ΣΞ ࠓ৓ ળۣ

    @yiamjo QPUBUPUJQTJOϚωʔϑΥϫʔυࣾ
  2. Swift 5 async/await ݚڀಡຊ IUUQTCPPUIQNKBJUFNT 0QUJPOBM ٕज़ಉਓࢽΛ࡞Γ·ͨ͠

  3. ຊ୊

  4. ݱࡏͷSwift 4.1͸ async/awaitΛαϙʔτ͍ͯ͠ͳ͍ - Xcode 10ͷSwift 4.2Ͱ΋async/await͸ͳ͍

  5. 2017/8 SwiftͷੜΈͷ਌ΫϦεࢯ͔Β async/awaitϓϩϙʔβϧͷυϥϑτ͕ Swift EvolutionͷMLʹ౤ߘ͞ΕΔ

  6. ͜ͷϓϩϙʔβϧʹ͍ͭͯ ಈػίϯϓϦʔγϣϯϋϯυϥ͸࠷దͰ͸ͳ͍ ղܾࡦ͸ίϧʔνϯ 0CK$Πϯϙʔλͷม׵ طଘػೳͱͷ૬ޓ࡞༻ աڈͷίʔυͱͷޓ׵ੑ "#*TUBCJMJUZ΁ͷӨڹ ଞͷγϯλοΫε ୅ସҊ কདྷతͳํ޲ੑ

    w ΫϩʔδϟͰίʔϧόοΫ͢Δͱίʔυ͕ωετ͍ͯͬͯ͠͠·͏ w ΤϥʔॲཧΛϋϯυϥ͝ͱʹॻ͘ͷ͸ࠔ೉ w ৚݅ʹΑͬͯΫϩʔδϟΛݺͼग़͢ͷ͸ۤ௧ w ؔ਺͕஋Λฦ͔͢ɺதஅ͢Δ͜ͱΛՄೳʹ͢Δ w δΣωϨʔλʢZJFMEʣ΍ඇಉظϞσϧͦͷଞͷػೳΛ࣮૷͢Δͷʹ࢖༻Ͱ͖Δ w ͜ͷϓϩϙʔβϧͰ͸ίϯϓϦʔγϣϯϋϯυϥͷଟ͘ͷ໰୊Λഉআ w ࠷΋ҰൠతͳϢʔεέʔεʹ޲໋໊͔ͬͯ๏ͱ༻ޠΛόΠΞε͢Δ w BTZOD͔ZJFMET͔ʹ͍ͭͯ͸ίΞηϚϯςΟΫεʹ͸ؔ܎͠ͳ͍ w ఏҊ͢ΔίϧʔνϯϞσϧ͸ΠϯλϑΣʔεͰ͸ͳ͍ w 0CK$ͷίϯϓϦʔγϣϯϋϯυϥϕʔεͷ"1*Λ 4XJGUͰ࢖͑ΔΑ͏ ม׵͢Δ w BTZODؔ਺΋UISPXTͰ͖ΔΑ͏ʹ͠ɺUSZBXBJUͰϋϯυϦϯάͰ͖ΔΑ͏ʹ͢Δ w ίϯύΠϥ͸Ϋϩʔδϟ͕ඇಉظ͔Ͳ͏͔؆୯ʹ൑ఆͰ͖Δ w EFGFS͸ίϧʔνϯ͕ഁغ͞Εͨࡍʹ΋ಈ࡞͢ΔΑ͏ʹ͢Δ w ʢϋϯυϥͳΒҾ਺Λ૿΍͕͢ʣBTZODͳSFUVSO͸݁ՌΛλϓϧͰฦͤΔ w ίϯύΠϥ͕ANZ2VFVFBTZOD\^Aͳهड़Λݕग़ͯ͠pYJUͰमਖ਼Ͱ͖Δ w "#*4UBCJMJUZʹӨڹ͠ͳ͍ w BTZODͳΒUISPXTͱ͢Δͱύλʔϯ͸ݮΔ͕ܽ఺͸͋Δ w BTZODͳΒσϑΥϧτUISPXTʹ͠ɺBTZOD OPOUISPXJOH ʹ͢Δͷ΋ܽ఺͸͋Δ w ίϧʔνϯΛ༻ҙ͍ͨ͠ͷͰ͋ͬͯBTZODBXBJUΛ࣮૷͍ͨ͠ͷͰ͸ͳ͍ w $ͷΑ͏ʹҰൠతͳBTZODBXBJU͸'VUVSFΫϥεΛฦ͢͜ͱʹͳΔ w ͦ͏ͳΔͱBTZODBXBJUΛݴޠϨϕϧͰ࣮૷͢Δ͜ͱʹͳͬͯ͠·͏ w ͜ͷఏҊ͸AYBXBJUGPP CBS AͷΑ͏ʹνΣΠχϯάΛ͏·͘Ͱ͖Δ w ۩ମྫ͸ͳ͍͕͜ͷఏҊ͔Βকདྷ΁ͷ֦ுੑɺ΍͍͖ͬͯΛड़΂͍ͯΔ
  7. - 2017/8 Swift EvolutionͷϦϙδτϦʹSwift 5 ͷ༧ఆͱͯ͠ɺඇಉظॲཧͷ৽͍͠جૅΛ࡞ Δͱ͍͏͜ͱ͕௥ه͞Εͨ - https://github.com/apple/swift-evolution

  8. ઌʹൃදͷ݁࿦Λ·ͱΊΔ

  9. KotlinͱSwiftͷasync/awaitڞ௨఺ • Kotlinͷasync/await΍suspend͸ඇಉظؔ਺ʹ ΩʔϫʔυΛ෇͚Δ • Kotlinͷsuspend͕ಛʹSwiftͷʹࣅ͍ͯΔ • ͔͠͠ඍົͳҧ͍͕͋Δ

  10. ͦ΋ͦ΋async/awaitͬͯ ԿΑʁ

  11. async/await͸ ඇಉظॲཧΛಉظॲཧతʹ ίʔσΟϯάͰ͖Δ ඇಉظॲཧΛ଴ͭ ίʔϧόοΫ஍ࠈʹͳΒͳͯ͘ࡁΉͶʂ

  12. Swift 5ͷυϥϑτʹ͋Δasync/awaitͷྫ // ඇಉظॲཧΛ࣮ߦ͠໭Γ஋Λͦͷ݁Ռͱ͢Δؔ਺ func loadWebResource(_ path: String) async ->

    Resource func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image // ඇಉظॲཧΛ࣮ߦ͠Web্͔ΒσʔλΛऔಘ͠ը૾Λͭ͘Δؔ਺ func processImageData1() async -> Image { let dataResource = await loadWebResource("dataprofile.txt") let imageResource = await loadWebResource(“imagedata.dat") let imageTmp = await decodeImage(dataResource, imageResource) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult }
  13. Swift 5ͷυϥϑτʹ͋Δasync/awaitͷྫ // ඇಉظॲཧΛ࣮ߦ͠໭Γ஋Λͦͷ݁Ռͱ͢Δؔ਺ func loadWebResource(_ path: String) async ->

    Resource func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image // ඇಉظॲཧΛ࣮ߦ͠Web্͔ΒσʔλΛऔಘ͠ը૾Λͭ͘Δؔ਺ func processImageData1() async -> Image { let dataResource = await loadWebResource("dataprofile.txt") let imageResource = await loadWebResource(“imagedata.dat") let imageTmp = await decodeImage(dataResource, imageResource) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult } ؔ਺ఆٛ࣌ʹBTZODΛ͚ͭΔ
  14. Swift 5ͷυϥϑτʹ͋Δasync/awaitͷྫ // ඇಉظॲཧΛ࣮ߦ͠໭Γ஋Λͦͷ݁Ռͱ͢Δؔ਺ func loadWebResource(_ path: String) async ->

    Resource func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image // ඇಉظॲཧΛ࣮ߦ͠Web্͔ΒσʔλΛऔಘ͠ը૾Λͭ͘Δؔ਺ func processImageData1() async -> Image { let dataResource = await loadWebResource("dataprofile.txt") let imageResource = await loadWebResource(“imagedata.dat") let imageTmp = await decodeImage(dataResource, imageResource) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult } ؔ਺ఆٛ࣌ʹBTZODΛ͚ͭΔ BXBJUͰ݁ՌΛ଴ͬͯऔΓग़͢Α͏ʹ هड़Ͱ͖·͢
  15. Kotlin 1.2.51ͷasync/await BTZODBXBJU͸·ͩFYQFSJNFOUBM͔ͩΒ ͙͢มߋ͞ΕΔ͔΋͠Εͳ͍Α

  16. Kotlin async/awaitͰಉ͡ྫΛهड़ͯ͠ΈΔ fun loadWebResource(resource: String): Deferred<Resource> = async { //

    ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ // @asyncͰDeferredίϯςφʹ͘Δ·ΕΔʁ return@async Resource() } fun processImageData1(): Deferred<Image> = async { val dataResource = loadWebResource("data.txt").await() val imageResource = loadWebResource("imagedata.dat").await() val imageTmp = decodeImage(dataResource, imageResource).await() val imageResult = dewrapAndCleanupImage(imageTmp).await() return@async imageResult }
  17. Kotlin async/awaitͰಉ͡ྫΛهड़ͯ͠ΈΔ fun loadWebResource(resource: String): Deferred<Resource> = async { //

    ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ // @asyncͰDeferredίϯςφʹ͘Δ·ΕΔʁ return@async Resource() } fun processImageData1(): Deferred<Image> = async { val dataResource = loadWebResource("data.txt").await() val imageResource = loadWebResource("imagedata.dat").await() val imageTmp = decodeImage(dataResource, imageResource).await() val imageResult = dewrapAndCleanupImage(imageTmp).await() return@async imageResult } %FGFSSFEΛฦ͢
  18. Kotlin async/awaitͰಉ͡ྫΛهड़ͯ͠ΈΔ fun loadWebResource(resource: String): Deferred<Resource> = async { //

    ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ // @asyncͰDeferredίϯςφʹ͘Δ·ΕΔʁ return@async Resource() } fun processImageData1(): Deferred<Image> = async { val dataResource = loadWebResource("data.txt").await() val imageResource = loadWebResource("imagedata.dat").await() val imageTmp = decodeImage(dataResource, imageResource).await() val imageResult = dewrapAndCleanupImage(imageTmp).await() return@async imageResult } BXBJU ͸%FGFSSFEίϯςφͷϝιου %FGFSSFEΛฦ͢
  19. Kotlin way

  20. Kotlin suspendͰಉ͡ྫΛهड़ suspend fun loadWebResource2(): Resource { // ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ͍ͯ͠Δײ͡ return

    Resource() } suspend fun processImageData2(): Image { val dataResource = loadWebResource2("data.txt") val imageResource = loadWebResource2("imagedata.dat") val imageTmp = decodeImage2(dataResource, imageResource) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult }
  21. Kotlin suspendͰಉ͡ྫΛهड़ suspend fun loadWebResource2(): Resource { // ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ͍ͯ͠Δײ͡ return

    Resource() } suspend fun processImageData2(): Image { val dataResource = loadWebResource2("data.txt") val imageResource = loadWebResource2("imagedata.dat") val imageTmp = decodeImage2(dataResource, imageResource) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult } ؔ਺ଆʹTVTQFOEΩʔϫʔυ෇͚ͯ%FGFSSFEͰͳ͘஋Λฦ͢
  22. Kotlin suspendͰಉ͡ྫΛهड़ suspend fun loadWebResource2(): Resource { // ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ͍ͯ͠Δײ͡ return

    Resource() } suspend fun processImageData2(): Image { val dataResource = loadWebResource2("data.txt") val imageResource = loadWebResource2("imagedata.dat") val imageTmp = decodeImage2(dataResource, imageResource) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult } ؔ਺ଆʹTVTQFOEΩʔϫʔυ෇͚ͯ%FGFSSFEͰͳ͘஋Λฦ͢ ݺͼग़͠ଆͰBXBJU͢Δඞཁ͕ͳ͘ͳΔ
  23. ͔͠͠… ͓෼͔Γ͍͚ͨͩͨͩΖ͏͔… ͜ͷྫͷsuspend͸ ແବʹ଴ͬͯ͠·͍ͬͯΔ

  24. ͜ͷॲཧͷແବͳͱ͜Ζ͸ʁ suspend fun loadWebResource2(): Resource { // ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ͍ͯ͠Δײ͡ return Resource()

    } suspend fun processImageData2(): Image { val dataResource = loadWebResource2("data.txt") val imageResource = loadWebResource2(“imagedata.dat") val imageTmp = decodeImage2(dataResource, imageResource) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult }
  25. ͜ͷॲཧͷແବͳͱ͜Ζ͸ʁ suspend fun loadWebResource2(): Resource { // ͦͷ··ฦ͚͢Ͳຊ౰͸ඇಉظॲཧ͍ͯ͠Δײ͡ return Resource()

    } suspend fun processImageData2(): Image { val dataResource = loadWebResource2("data.txt") val imageResource = loadWebResource2(“imagedata.dat") val imageTmp = decodeImage2(dataResource, imageResource) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult } MPBE8FC3FTPVSDF͸ؔ࿈͠ͳ͍ඇಉظॲཧͳͷͰ ͭಉ࣌ʹ࣮ߦͯ݁͠ՌΛ଴ͯ͹ޮ཰͍͍ͷͰ͸ʁ
  26. Kotlin suspendΛasyncͰแΊ͹ෳ਺ॲཧͷ଴ͪ߹ΘͤͰ͖Δ suspend fun processImageData2(): Image { val dataResource =

    async { loadWebResource3(“data.txt”) } val imageResource = async { loadWebResource3(“imagedata.dat”) } val imageTmp = decodeImage2(dataResource.await(), imageResource.await()) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult }
  27. Kotlin suspendΛasyncͰแΊ͹ෳ਺ॲཧͷ଴ͪ߹ΘͤͰ͖Δ suspend fun processImageData2(): Image { val dataResource =

    async { loadWebResource3(“data.txt”) } val imageResource = async { loadWebResource3(“imagedata.dat”) } val imageTmp = decodeImage2(dataResource.await(), imageResource.await()) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult } TVTQFOEͳؔ਺ͦͷ··ΛBTZODͰ͘ΔΜͰ%FGFSSFEʹ
  28. Kotlin suspendΛasyncͰแΊ͹ෳ਺ॲཧͷ଴ͪ߹ΘͤͰ͖Δ suspend fun processImageData2(): Image { val dataResource =

    async { loadWebResource3(“data.txt”) } val imageResource = async { loadWebResource3(“imagedata.dat”) } val imageTmp = decodeImage2(dataResource.await(), imageResource.await()) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult } TVTQFOEͳؔ਺ͦͷ··ΛBTZODͰ͘ΔΜͰ%FGFSSFEʹ %FGFSSFEͳͷͰBXBJU Ͱ͖ΔΑ͏ʹͳͬͨ
  29. Kotlin suspendΛasyncͰแΊ͹ෳ਺ॲཧͷ଴ͪ߹ΘͤͰ͖Δ suspend fun processImageData2(): Image { val dataResource =

    async { loadWebResource3(“data.txt”) } val imageResource = async { loadWebResource3(“imagedata.dat”) } val imageTmp = decodeImage2(dataResource.await(), imageResource.await()) val imageResult = dewrapAndCleanupImage2(imageTmp) return imageResult } TVTQFOEͳؔ਺ͦͷ··ΛBTZODͰ͘ΔΜͰ%FGFSSFEʹ %FGFSSFEͳͷͰBXBJU Ͱ͖ΔΑ͏ʹͳͬͨ ࣮ࡍ͸ٯʹɺ%FGFSSFEϝιουΛTVTQFOEͳϝιουͰ Ͱ͘ΔΉ΄͏͕සൟʹ͔ͭ͏ͩΖ͏ͱ͸ࢥ͍·͢ɻ
  30. Swift 5ͷasync/await΋FutureΛ࢖͑͹ ෳ਺ॲཧͷ଴ͪ߹Θ͕ͤͰ͖Δ func loadWebResource(_ path: String) async -> Resource

    func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image func processImageData1() async -> Image { let dataResource = Future { loadWebResource(“dataprofile.txt") } let imageResource = Future { loadWebResource(“imagedata.dat”) } let imageTmp = await decodeImage(dataResource.get(), imageResource.get()) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult }
  31. Swift 5ͷasync/await΋FutureΛ࢖͑͹ ෳ਺ॲཧͷ଴ͪ߹Θ͕ͤͰ͖Δ func loadWebResource(_ path: String) async -> Resource

    func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image func processImageData1() async -> Image { let dataResource = Future { loadWebResource(“dataprofile.txt") } let imageResource = Future { loadWebResource(“imagedata.dat”) } let imageTmp = await decodeImage(dataResource.get(), imageResource.get()) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult } ࣗલͷ'VUVSFͰ͘ΔΉ
  32. Swift 5ͷasync/await΋FutureΛ࢖͑͹ ෳ਺ॲཧͷ଴ͪ߹Θ͕ͤͰ͖Δ func loadWebResource(_ path: String) async -> Resource

    func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image func processImageData1() async -> Image { let dataResource = Future { loadWebResource(“dataprofile.txt") } let imageResource = Future { loadWebResource(“imagedata.dat”) } let imageTmp = await decodeImage(dataResource.get(), imageResource.get()) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult } ࣗલͷ'VUVSFͰ͘ΔΉ GVUVSFHFUϝιουͰ݁ՌΛ଴ͭ
  33. Swift 5ͷasync/await΋FutureΛ࢖͑͹ ෳ਺ॲཧͷ଴ͪ߹Θ͕ͤͰ͖Δ func loadWebResource(_ path: String) async -> Resource

    func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image func dewarpAndCleanupImage(_ i : Image) async -> Image func processImageData1() async -> Image { let dataResource = Future { loadWebResource(“dataprofile.txt") } let imageResource = Future { loadWebResource(“imagedata.dat”) } let imageTmp = await decodeImage(dataResource.get(), imageResource.get()) let imageResult = await dewrapAndCleanupImage(imageTmp) return imageResult } ࣗલͷ'VUVSFͰ͘ΔΉ GVUVSFHFUϝιουͰ݁ՌΛ଴ͭ ͭ·Γ,PUMJOͷTVTQFOEʹ͍ۙײ৮
  34. ͞Βʹ஌Γ͍ͨਓͷͨΊʹ

  35. Swift 5 async/await ݚڀಡຊ • ϥΠϒϥϦHydraͰSwift 4Ͱ΋async/awaitΛ࣮ݱ͢Δ • Hydra͕ͲͷΑ͏ʹͯ͠εϨουΛࢭΊ͍ͯΔ͔ղઆ •

    async/await ϓϩϙʔβϧυϥϑτͷղઆ • JS, C#, Dart, KotlinͰͷasync/awaitղઆ IUUQTCPPUIQNKBJUFNT