【増枠/increase】try! Swift Pre Talks 2019 - connpass https://tryswifttokyo-aftertalks.connpass.com/event/120987/ での発表資料です。
ܧଓ͠ͱܖʹΑΔઃܭContinuation-Passing Style and Design By Contractby.2019/3/19 try! Swift Pre Talks 20191
View Slide
takasek@takasekWorksOSS: ActionClosurableApp: PasteTheTypeArticlesʮίϯύΠϧΤϥʔϥϯλΠϜΤϥʔΛ͍͚ͯͩ͘͠ͰiOSΞϓϦͷ࡞Γํ͕Θ͔ΔϓϩδΣΫτʯʮ͓લΒ͕ModelͱݺͿΞϨΛͳΜͱݺͿ͖͔ʯʮiOSΞϓϦઃܭύλʔϯೖʯʢڞஶʣ2
ʮiOSΞϓϦઃܭύλʔϯೖʯධൃചதʂhttps://peaks.cc/takasek/iOS_architecturetakasek୲ষୈ1ষʮઃܭ͢Δͱ͍͏͜ͱʯୈ2ষʮઃܭʹύλʔϯΛద༻͢Δલʹʯୈ3ষʮSwiftΒ͘͠ઃܭ͢Δʯୈ4ষʮΞʔΩςΫνϟͷύλʔϯΛௗᛌ͢Δʯ3
ܧଓ͠Continuation-Passing Style(CPS)4
// Without CPSfunc doSomething(i: Int) -> String {sleep(100)return "\(i)"}// With CPSfunc doSomething(i: Int, completion: @escaping (String) -> Void) {DispatchQueue.global().async {sleep(100)completion("\(i)")}}5
!6
func doSomething(i: Int,completion: @escaping (String) -> Void)͜ͷΠϯλϑΣʔεʹɺخ͘͠ͳ͍͕͋Γ·͢7
ʮ͋ͬɺಡΊͨʯ8
ʮίʔϧόοΫࠈͷͰ͠ΐʯ9
ҧ͍·͢10
ܖʹΑΔઃܭDesign By Contract11
ܖʹΑΔઃܭDesign By ContractΦϒδΣΫτࢦΛΊͨݚڀऀόʔτϥϯυɾϝΠϠʔʹΑΔɺ৴པੑͷߴ͍γεςϜΛߏங͢ΔͨΊͷΞΠσΞ12
ܖʹΑΔઃܭ͋Δϧʔνϯ͕ɺݺΕΔ૬खͱͷؒͰऔΓަΘܾ͢Ί͝ͱΛʮද໌ʯ͢Δ• ࣄલ݅ɿݺͿଆ͕͜ͷ݅Λอূ͢Δ߹ͷΈɺϧʔνϯॲཧΛਖ਼͘͠ߦ͏ҾͷܕͳͲͰදݱՄೳ• ࣄޙ݅ɿࣄલ͕݅कΒΕ͍ͯͨΒɺϧʔνϯͷ࣮ߦ݁Ռ͕อূ͢Δ݅ΓͷܕͳͲͰදݱՄೳࣄલ͕݅ഁΒΕɺࣄޙ݅ΛकΕͳ͍߹ྫ֎͕ൃੜ͢Δ• ෆม݅ ʹ͍ͭͯࠓճলུ13
ίʔυͱද໌ͷ۩ମྫfunc half(of i: Int) throws -> Int {assert(i.isMultiple(of: 2))if !i.isMultiple(of: 2) { throw Error.isOdd }return i / 2}• ࣄલ݅:• Int ͔͠ड͚͚ͭ·ͤΜ• ۮ͔͠ड͚͚ͭ·ͤΜ (ܕͱͯ͠දݱෆೳ)• ࣄޙ݅: ඞͣ Int Λฦ͠·͢• ྫ֎: ۮͰͳ͔ͬͨ߹ྫ֎Λ͛·͢14
ʮܖʹΑΔઃܭʯͷ࣮ݱͷͨΊʹɺSwiftͷܕ͚େཱ͖͍ͬͯ͘Δ15
ͯ͞16
func half(of i: Int) throws -> Int {if !i.isMultiple(of: 2) {throw Error.isOdd}return i / 2}͜ΕΛCPSʹมͯ͠Έ·͠ΐ͏17
func half(of i: Int, completion: (Int) -> Void) {if !i.isMultiple(of: 2) {return}completion(i / 2)}18
19
OK, حͷ߹֬ೝ͠Α͏ʂ20
21
ݺΕͳ͍…ʁ22
23
completionͷݺͼ࿙Ε24
func half(of i: Int, completion: (Int) -> Void) {if !i.isMultiple(of: 2) {return //!}completion(i / 2)}25
enum Result {case success(T)case error(Error)}func half(of i: Int, completion: (Result) -> Void) {if !i.isMultiple(of: 2) {return //!}completion(.success(i / 2))}26
enum Result {case success(T)case error(Error)}func half(of i: Int, completion: (Result) -> Void) {if !i.isMultiple(of: 2) {completion(.error(.isOdd)) //}completion(.success(i / 2))}27
ͬͨʂ͏ҰڍಈΛ֬ೝ͠Α͏ʂ28
29
2ݺΕ͍ͯΔ…ͩͱ…ʁ30
func half(of i: Int, completion: (Result) -> Void) {if !i.isMultiple(of: 2) {completion(.error(.isOdd))//!}completion(.success(i / 2))}31
func half(of i: Int, completion: (Result) -> Void) {if !i.isMultiple(of: 2) {completion(.error(.isOdd))return //!}completion(.success(i / 2))}32
ܧଓ͠ελΠϧΛ͏ͱ੩తܕ͚ͷԸܙΛड͚ΒΕͳ͍33
ͳͥͳͷ͔ΓͷܕʹΑͬͯࣄޙ݅ΛදݱͰ͖ͳ͍͔Β(T, (U) -> Void) -> VoidVoid࠷ऑͷࣄޙ݅34
Ͳ͏͢Ε͍͍͔ΓͷܕʹΑͬͯࣄޙ݅Λදݱ͢Ε͍͍(T) -> XXXʮ͍ͣΕ݁Ռ͕ಘΒΕΔʯ͜ͱΛܕ͚ͰࣔͤΕɺඇಉظॲཧͰΓΛػೳͤ͞ΒΕΔ35
func half(of i: Int) -> RxSwift.Single {if !i.isMultiple(of: 2) {return .error(Error.isOdd)}return .just(i / 2)}͜ΕͳΒ੩తܕ͚ͷԸܙΛड͚ͭͭɺʮඇಉظͰ͋Δ͜ͱʯΛදݱͰ͖Δ36
• Promise(Future) ύλʔϯ• PromiseK• Hydra• RxSwift• etc• async/await• comming soon in Swift 5.x!?• ͜ͷݴޠ༷Λϕʔεʹ Future ܕΛߏஙՄೳCPSΛશ໘తʹஔ͖͔͑Մೳ͔ͱ͍͏ͱ͍͕͠ɺબࢶΛͬͨ͏͑ͰύλʔϯΛબͼ͍ͨ37
݁ɾਓؒϛεΛ͠·͢ɾϛεΛ͢Δલʹɺද໌ΛίϯύΠϥ͕͔ΔܗͰॻ͚ͳ͍͔ҙࣝ͠ͳ͕Βઃܭ͠·͠ΐ͏38
͓·͚ͱͯ5ͰޠΓ͖Εͳ͍39
ʮද໌ʯʹ͍ͭͯͷิ• ҾɾΓͷܕ͚͕ͩද໌Ͱͳ͍ͱݴ͚ͬͨΕͲ…• assert ͚ͩͰͳ͘ɺSwiftͰݴ͑ generics conditional conformanceද໌ͷํ๏• ͭʹɺίϯύΠϥղऍෆೳͳද໌ྑ͘ͳ͍…Θ͚Ͱͳ͍• දݱྗΛ্͛Δͱֶशίετɾෳࡶੑ͕ϖΠ͠ͳ͍͜ͱଟ͍ͷͰɺͦ͜όϥϯε• ͨͱ͑ɺڽͬͨprotocolͷwhere۟ɺৗਓʹཧղग़དྷΔ͔ͬͯݴΘΕΔͱݫ͍͠ΑͶ…ɹ40
ิͷิٯʹݴ͑ɺܖʹΑΔઃܭݴޠΛΘͣద༻Մೳͳ֓೦Ͱ͢t_wada͞ΜʹΑΔ͋͑ͯPHPΛϕʔεʹͨ͠εϥΠυPHPer͡Όͳͯ͘ΦεεϝͰ͢https://speakerdeck.com/twada/php-conference-201641
ʮܧଓ͠ʯʹ͍ͭͯͷิ• ࣮ async/awaitʮ෦తͳCPSมʯͦͷͷͱ͍͑·͢Continuation Passing Style Revisited– Fabulous Adventures In Codinghttps://blogs.msdn.microsoft.com/ericlippert/2010/10/21/continuation-passing-style-revisited-part-one/ͦͷ༁matarillo.com: ܧଓ͠ελΠϧ(CPS)ͱඇಉظߏจ(async/await)https://matarillo.com/general/cps42
Swiftͷ async/await ͱܧଓͱ Future ͷؔChris Lattnerͷproposal2ʹΑΔͱɺ• ଞͷݴޠͰ Future ͕·ͣ͋ͬͯɺͦͷ্ʹasync/await͕͔͍ͬͬͯΔ• Swiftͷasync/awaitͷઃܭͰͦΕΛલఏͱͤͣɺܧଓΛͦͷ··ѻ͏खஈΛ࿐ग़͍ͤͯ͞Δ• ͱ͍͑ Future ͱ͍͏ܕ͚͞Εͨঢ়ଶͰѻ͏ΠϯλϑΣʔεߏஙՄೳͰ͢Αɺͱ͍͏͜ͱ2 https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619yimajo͞Μͷʮasync/awaitݚڀಡຊʯ͋ΘͤͯͲ͏ͧ43
ؔ࿈ɿʮܖʹΑΔઃܭʯΛΩʔϫʔυͰ֦ு͢ΔʮܖʹΑΔઃܭʯʹ͍ͭͯৄղ͞Ε͍ͯΔʮΦϒδΣΫτࢦೖʯʹɺඇಉظʢฒߦʣॲཧΛͱʹ֦ுͨ͠߹ͷܖͷϙϦγʔʹ͍ͭͯͷٞ͋Γ·͢໘ന͍Αʂ44