Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift と Protocol 指向

Elvis Shi
February 02, 2018

Swift と Protocol 指向

Elvis Shi

February 02, 2018
Tweet

More Decks by Elvis Shi

Other Decks in Programming

Transcript

  1. var employedBy = "YUMEMI Inc." var job = "iOS Developer"

    var favoriteLanguage = "Swift" var twitter = "@lovee" var qiita = "lovee" var github = "el-hoshino" var additionalInfo = """ ΏΔΏΔΩϟϯϓ΋͘΋͘ձɺࢀՃऀืूத """ class Me: Developable, Talkable { }
  2. ਆ͸ݴͬͨɻੈʹΠοψ͋Εɻ // ਆ͸ݴͬͨɻੈʹΠοψ͋Εɻ struct Dog { // ΠοψΛఆٛ } //

    ਆ͸ݴͬͨɻੈͷΠοψʹ໐͖੠͋Εɻ func shout(dog: Dog) { // Ποψͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print("ʢ∪ʈωʈʣΘΜΘΜ͓ʂ") } let dog = Dog() shout(dog: dog) // ʢ∪ʈωʈʣΘΜΘΜ͓ʂ
  3. ਆ͸ݴͬͨɻੈʹωοί͋Εɻ // ਆ͸ݴͬͨɻੈʹΠοψ͋Εɻ struct Dog { // ΠοψΛఆٛ } //

    ਆ͸ݴͬͨɻੈͷΠοψʹ໐͖੠͋Εɻ func shout(dog: Dog) { // Ποψͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print("ʢ∪ʈωʈʣΘΜΘΜ͓ʂ") } let dog = Dog() shout(dog: dog) // ʢ∪ʈωʈʣΘΜΘΜ͓ʂ // ਆ͸ݴͬͨɻੈʹωοί͋Εɻ struct Cat { // ωοίΛఆٛ } // ਆ͸ݴͬͨɻੈͷωοίʹ໐͖੠͋Εɻ func shout(cat: Cat) { // ωοίͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print("ฅ(=ŋωŋ=)ฅʹΌʔΜ") } let cat = Cat() shout(cat: cat) // ฅ(=ŋωŋ=)ฅʹΌʔΜ ⛭״猺ؤע؆猻نڋٜخ
 寨㡑⦿㧙ק؆׫؂؋؆إ؆נ
  4. ਆ͸ݴͬͨɻੈʹωοί͋Εɻ // ਆ͸ݴͬͨɻੈʹΠοψ͋Εɻ struct Dog { // ΠοψΛఆٛ } //

    ਆ͸ݴͬͨɻੈͷΠοψʹ໐͖੠͋Εɻ func shout(dog: Dog) { // Ποψͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print("ʢ∪ʈωʈʣΘΜΘΜ͓ʂ") } let dog = Dog() shout(dog: dog) // ʢ∪ʈωʈʣΘΜΘΜ͓ʂ // ਆ͸ݴͬͨɻੈʹωοί͋Εɻ struct Cat { // ωοίΛఆٛ } // ਆ͸ݴͬͨɻੈͷωοίʹ໐͖੠͋Εɻ func shout(cat: Cat) { // ωοίͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print("ฅ(=ŋωŋ=)ฅʹΌʔΜ") } let cat = Cat() shout(cat: cat) // ฅ(=ŋωŋ=)ฅʹΌʔΜ ⛭״猺ؤע؆猻نڋٜخ
 寨㡑⦿㧙ק؆׫؂؋؆إ؆נ
  5. ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { var sound: String {

    // ໐͖੠Λఆٛͯ͠ fatalError("Implement Me!") } func shout() { // ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } // ਆ͸ݴͬͨɻੈʹΠοψ͋ΕɻΠοψ͸ಈ෺Ͱ͋Εɻ class Dog: Animal { // ΠοψΛ࣮૷ override var sound: String { return "ʢ∪ʈωʈʣΘΜΘΜ͓ʂ" } } let dog = Dog() dog.shout() // ʢ∪ʈωʈʣΘΜΘΜ͓ʂ // ਆ͸ݴͬͨɻੈʹωοί͋Εɻωοί͸ಈ෺Ͱ͋Εɻ class Cat: Animal { // ωοίΛ࣮૷ override var sound: String { return "ฅ(=ŋωŋ=)ฅʹΌʔΜ" } } let cat = Cat() cat.shout() //ฅ(=ŋωŋ=)ฅʹΌʔΜ
  6. ਆ͸ݴͬͨɻΠοψ΋ωοί΋ಈ෺Ͱ͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { var sound: String {

    // ໐͖੠Λఆٛͯ͠ fatalError("Implement Me!") } func shout() { // ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } 濕ש⯑׼׭⹻劊׵ب،
 طٖٟ؞٠ٖن؞濕׭ا // ਆ͸ݴͬͨɻੈʹΠοψ͋ΕɻΠοψ͸ಈ෺Ͱ͋Εɻ class Dog: Animal { // ΠοψΛ࣮૷ override var sound: String { return "ʢ∪ʈωʈʣΘΜΘΜ͓ʂ" } } let dog = Dog() dog.shout() // ʢ∪ʈωʈʣΘΜΘΜ͓ʂ // ਆ͸ݴͬͨɻੈʹωοί͋Εɻωοί͸ಈ෺Ͱ͋Εɻ class Cat: Animal { // ωοίΛ࣮૷ override var sound: String { return "ฅ(=ŋωŋ=)ฅʹΌʔΜ" } } let cat = Cat() cat.shout() //ฅ(=ŋωŋ=)ฅʹΌʔΜ
  7. ਆ͸ݴͬͨɻΠοψ΋ωοί΋ಈ෺Ͱ͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { var sound: String {

    // ໐͖੠Λఆٛͯ͠ fatalError("Implement Me!") } func shout() { // ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } عٖو؋▶䕊؆؊؇▶䕊؊
 屢⇗䅡׻ױ؆ק׿׻ئֻ
 㠲㌆憫؋▶䕊״؟؆נ؊؇
 ▶䕊؊ٴِٖٜר㸓׳נר
 ׻؝؇▶䕊خ偺㕠׳׻ئ // ਆ͸ݴͬͨɻੈʹ΢οα͋Εɻ΢οα͸ಈ෺Ͱ͋Εɻ class Rabbit: Animal { // ΢οαΛ࣮૷ override var sound: String { fatalError("΢οα͸໐͔ͳ͍") } } let rabbit = Rabbit() //rabbit.shout() // Fatal error: ΢οα͸໐͔ͳ͍ // ਆ͸ݴͬͨɻੈʹٹٸं͋ΕɻٹٸंʹαΠϨϯ͋Εɻ class Ambulance: Animal { // ٹٸंͷαΠϨϯΛ໐Β͍͚ͨͩ͠ͷͨΊʹAnimalΛܧঝͪ͠Όͬͨ override var sound: String { return "ϐʔϙʔϐʔϙʔ" } } let ambulance = Ambulance() ambulance.shout() //ϐʔϙʔϐʔϙʔ
  8. Animal Cat Dog Rabbit Ambulance Shoutable Animal RedColorRecog- nizableAnimal 濕׫㵀叞

    恅啓嵮帹㵀叞 濕׭ا׳恅啓؞嵮帹؃שا ׳ק׳⯻撮偺㕠؃ש؆נ ⇓桴؋׶ب
  9. 0CKFDU0SJFOUFE1SPHSBNNJOH ‣ ΦϒδΣΫτࢦ޲ͷʮܧঝʯؔ܎͸ຊདྷJTBؔ܎ ‣ αϒΫϥε͸ʮ਌ΫϥεͰ͋Δʯඞཁ͕͋Δ ‣ ਌Ϋϥε͸ຊདྷʮఆٛʯʹઐ೦͢΂͖ ‣ ʮಈ෺ʯΫϥεΛ࡞Δͱ͍͏ͷ͸ɺʮಈ෺ͱ͸Կ͔ʯΛఆٛ͢΂͖ ‣

    શͯͷಈ෺͕͋ΔΘ͚Ͱ͸ͳ͍ʮ໐͘ʯ΍ʮ੺৭ೝࣝʯػೳ͸ɺຊདྷ ʮಈ෺ʯͱͯ͠ͷػೳͰ࣮૷͢΂͖Ͱ͸ͳ͍ ‣ ͳͷʹΈΜͳʮ࢖͏͔ΒʯͱݴͬͯͱΓ͋͑ͣ਌Ϋϥεʹ৭Μͳػೳ ࣋ͨͤ͗͢ ‣ ͍ΘΏΔ(PE$MBTTͷ஀ੜ
  10. 1SPUPDPM0SJFOUFE1SPHSBNNJOH ‣ ϓϩτίϧࢦ޲ͷʮܧঝʢ४ڌʣʯ͸DBOEPؔ܎ ‣ ϓϩτίϧ΁ͷ४ڌ͸ʮͰ͖Δʯ͜ͱΛ͚ࣔͩ͢ ‣ ϓϩτίϧʹ४ڌͨ͠ܕ͕ͳΜͷܕ͔Λؾʹ͢Δඞཁ͕ͳ͍ ‣ ʮ໐͚ΔʯͳΒ໰୊ͳ͍ɺಈ෺ͩΖ͏͔޻ۀ੡඼ͩΖ͏͔ؔ܎ͳ͍ ‣

    DMBTTͰ΋TUSVDUͰ΋FOVNͰ΋ϓϩτίϧʹ४ڌͰ͖Δ ‣ ϓϩτίϧΛ֦ுͰରԠͰ͖ΔͨΊଟॏܧঝʢ४ڌʣ΋໰୊ͳ͍ ‣ ඞཁʹԠͯ͡σϑΥϧτಈ࡞ΛఆٛͰ͖Δ ‣ ඞཁʹԠ࣮ͯ͡ࡍͷܕ৘ใΛอཹͰ͖Δ
  11. ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { var sound: String {

    // ໐͖੠Λఆٛͯ͠ fatalError("Implement Me!") } func shout() { // ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } }
  12. ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { // ಈ෺ͷఆٛʹઐ೦ } protocol

    ShoutableType { // ʮ໐͘ʯ͜ͱ͕Մೳͳߏ੒͚ͩΛఆٛ var sound: String { get } func shout() } extension ShoutableType where Self: Animal { // ֦ுͰಈ෺ͷ৔߹ͷσϑΥϧτಈ࡞Λ࣮૷Մೳ func shout() { // ಈ෺ͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } extension؃Self؇ؤا ًغ٠ٽقٌר≠פا
  13. ਆ͸ݴͬͨɻੈʹΠοψ͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { // ಈ෺ͷఆٛʹઐ೦ } protocol

    ShoutableType { // ʮ໐͘ʯ͜ͱ͕Մೳͳߏ੒͚ͩΛఆٛ var sound: String { get } func shout() } extension ShoutableType where Self: Animal { // ֦ுͰಈ෺ͷ৔߹ͷσϑΥϧτಈ࡞Λ࣮૷Մೳ func shout() { // ಈ෺ͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } // ਆ͸ݴͬͨɻੈʹΠοψ͋ΕɻΠοψ͸ಈ෺Ͱ͋Εɻ class Dog: Animal { // ΠοψΛ࣮૷ } // ਆ͸ݴͬͨɻΠοψ͸໐͚ΔΑ͏ʹͳΕɻ extension Dog: ShoutableType { var sound: String { return "ʢ∪ʈωʈʣΘΜΘΜ͓ʂ" } } let dog = Dog() dog.shout() // ʢ∪ʈωʈʣΘΜΘΜ͓ʂ
  14. ਆ͸ݴͬͨɻੈʹωοί͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { // ಈ෺ͷఆٛʹઐ೦ } protocol

    ShoutableType { // ʮ໐͘ʯ͜ͱ͕Մೳͳߏ੒͚ͩΛఆٛ var sound: String { get } func shout() } extension ShoutableType where Self: Animal { // ֦ுͰಈ෺ͷ৔߹ͷσϑΥϧτಈ࡞Λ࣮૷Մೳ func shout() { // ಈ෺ͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } // ਆ͸ݴͬͨɻੈʹωοί͋Εɻωοί͸ಈ෺Ͱ͋Εɻ class Cat: Animal { // ωοίΛ࣮૷ } // ਆ͸ݴͬͨɻωοί͸໐͚ΔΑ͏ʹͳΕɻ extension Cat: ShoutableType { var sound: String { return "ฅ(=ŋωŋ=)ฅʹΌʔΜ" } } let cat = Cat() cat.shout() //ฅ(=ŋωŋ=)ฅʹΌʔΜ
  15. ਆ͸ݴͬͨɻੈʹ΢οα͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { // ಈ෺ͷఆٛʹઐ೦ } protocol

    ShoutableType { // ʮ໐͘ʯ͜ͱ͕Մೳͳߏ੒͚ͩΛఆٛ var sound: String { get } func shout() } extension ShoutableType where Self: Animal { // ֦ுͰಈ෺ͷ৔߹ͷσϑΥϧτಈ࡞Λ࣮૷Մೳ func shout() { // ಈ෺ͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } // ਆ͸ݴͬͨɻੈʹ΢οα͋Εɻ΢οα͸ಈ෺Ͱ͋Εɻ class Rabbit: Animal { // ΢οαΛ࣮૷ } let rabbit = Rabbit() //rabbit.shout() // Compile Error: value of type 'Rabbit' has no member 'shout'
  16. ਆ͸ݴͬͨɻੈʹٹٸं͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { // ಈ෺ͷఆٛʹઐ೦ } protocol

    ShoutableType { // ʮ໐͘ʯ͜ͱ͕Մೳͳߏ੒͚ͩΛఆٛ var sound: String { get } func shout() } extension ShoutableType where Self: Animal { // ֦ுͰಈ෺ͷ৔߹ͷσϑΥϧτಈ࡞Λ࣮૷Մೳ func shout() { // ಈ෺ͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } // ਆ͸ݴͬͨɻੈʹٹٸं͋ΕɻٹٸंʹαΠϨϯ͋Εɻ class Ambulance: ShoutableType { // ٹٸंͷαΠϨϯԻΛఆٛ var sound: String { return "ϐʔϙʔϐʔϙʔ" } func shout() { // ٹٸंͷαΠϨϯͷϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } let ambulance = Ambulance() ambulance.shout() //ϐʔϙʔϐʔϙʔ
  17. ਆ͸ݴͬͨɻੈʹωοί͋Εɻ // ਆ͸ݴͬͨɻੈʹಈ෺͋Εɻಈ෺ʹ໐͖੠͋Εɻ class Animal { // ಈ෺ͷఆٛʹઐ೦ } protocol

    ShoutableType { // ʮ໐͘ʯ͜ͱ͕Մೳͳߏ੒͚ͩΛఆٛ var sound: String { get } func shout() } extension ShoutableType where Self: Animal { // ֦ுͰಈ෺ͷ৔߹ͷσϑΥϧτಈ࡞Λ࣮૷Մೳ func shout() { // ಈ෺ͷ໐͘ϝΧχζϜΛ΄ʹΌΒΒ print(self.sound) } } // ਆ͸ݴͬͨɻੈʹωοί͋Εɻωοί͸ಈ෺Ͱ͋Εɻ class Cat: Animal { // ωοίΛ࣮૷ } // ਆ͸ݴͬͨɻωοί͸໐͚ΔΑ͏ʹͳΕɻ extension Cat: ShoutableType { var sound: String { return "ฅ(=ŋωŋ=)ฅʹΌʔΜ" } } protocol RedColorRecognizableType { // ੺৭ೝࣝʹඞཁͳ΋ͷΛఆٛ } // ਆ͸ߋʹݴͬͨɻωοί͸੺΋ೝࣝͰ͖ΔΑ͏ʹͳΕɻ extension Cat: RedColorRecognizableType { // ੺৭ೝࣝͷͨΊͷ࣮૷Λ΄ʹΌΒΒ }
  18. Animal Cat Dog Rabbit Ambulance Shoutable
 Animal RedColorRecog- nizableAnimal 濕׫㵀叞

    恅啓嵮帹㵀叞 濕׭ا׳恅啓؞嵮帹؃שا
 ׳ק׳⯻撮偺㕠؃ש؆נ ⇓桴؋׶ب
  19. ΋͠΋protocolʹSelf͕࢖͑ͳ͔ͬͨΒ // ΋͠ Self ͕࢖͑ͳ͔ͬͨΒ… protocol Equatable { func isEqual(to

    another: Equatable) -> Bool } protocol Comparable: Equatable { func isLess(than another: Comparable) -> Bool } struct AStruct { var p: Int }
  20. ΋͠΋protocolʹSelf͕࢖͑ͳ͔ͬͨΒ // ΋͠ Self ͕࢖͑ͳ͔ͬͨΒ… protocol Equatable { func isEqual(to

    another: Equatable) -> Bool } protocol Comparable: Equatable { func isLess(than another: Comparable) -> Bool } struct AStruct { var p: Int } extension AStruct: Equatable { func isEqual(to another: Equatable) -> Bool { guard let another = another as? AStruct else { return false } return self.p == another.p } } extension AStruct: Comparable { func isLess(than another: Comparable) -> Bool { guard let another = another as? AStruct else { fatalError("AStruct ͡Όͳ͔ͬͨΒͳΜͯฦ͢ͷʁ") } return self.p < another.p } }
  21. ͔͠͠4XJGUͷprotocol͸Self͕࢖͑Δʂ // ͔͠͠ Self ͕࢖͑Δʂ protocol Equatable { func isEqual(to

    another: Self) -> Bool } protocol Comparable: Equatable { func isLess(than another: Self) -> Bool } struct AStruct { var p: Int }
  22. ͔͠͠4XJGUͷprotocol͸Self͕࢖͑Δʂ // ͔͠͠ Self ͕࢖͑Δʂ protocol Equatable { func isEqual(to

    another: Self) -> Bool } protocol Comparable: Equatable { func isLess(than another: Self) -> Bool } struct AStruct { var p: Int } extension AStruct: Equatable { func isEqual(to another: AStruct) -> Bool { return self.p == another.p } } extension AStruct: Comparable { func isLess(than another: AStruct) -> Bool { return self.p < another.p } } ⩬㎦⬒ר㹬ױبا؊؃ֻ∺峩؆ـٶٌٛ؋屢إ؆נ
  23. ࣮ࡍͷ4XJGUʹ͓͚ΔEquatableͱComparableͷఆٛ // ࣮ࡍͷ Equatable ͱ Comparable ͷఆٛ protocol Equatable {

    static func == (lhs: Self, rhs: Self) -> Bool } protocol Comparable: Equatable { static func < (lhs: Self, rhs: Self) -> Bool } struct AStruct { var p: Int } extension AStruct: Equatable { static func == (lhs: AStruct, rhs: AStruct) -> Bool { return lhs.p == rhs.p } } extension AStruct: Comparable { static func < (lhs: AStruct, rhs: AStruct) -> Bool { return lhs.p < rhs.p } }
  24. ࣮ࡍͷ4XJGUʹ͓͚ΔEquatableͱComparableͷఆٛ // ࣮ࡍͷ Equatable ͱ Comparable ͷఆٛ protocol Equatable {

    static func == (lhs: Self, rhs: Self) -> Bool } protocol Comparable: Equatable { static func < (lhs: Self, rhs: Self) -> Bool } struct AStruct { var p: Int } extension AStruct: Equatable { static func == (lhs: AStruct, rhs: AStruct) -> Bool { return lhs.p == rhs.p } } extension AStruct: Comparable { static func < (lhs: AStruct, rhs: AStruct) -> Bool { return lhs.p < rhs.p } } let a = AStruct(p: 1) let b = AStruct(p: 2) a < b // true
  25. ΦϒδΣΫτࢦ޲ཁΒͳ͍ࢠٙ࿭ʁ ‣ ϓϩτίϧࢦ޲ʢ101ʣͱΦϒδΣΫτࢦ޲ʢ001ʣ͸ڞଘͰ͖Δ ‣ 101͸4XJGU͕ॳΊͯఏএͨ͠ख๏ ‣ 4XJGU͸ϚϧνύϥμΠϜݴޠ ‣ ͦ΋ͦ΋101͸طଘͷ001͕ۤखͳ෦෼Λิ׬͢ΔΑ͏ͳଘࡏ ‣

    ͲͬͪΛબͿͰ͸ͳ͘ɺ͏·͘ڞଘͤ͞Δ ‣ 101ʹΑΓɺੲclassͰ͔͠Ͱ͖ͳ͍ʢͨ͘͞Μͷʣ͜ͱ͕ࠓ protocolͷྗΛआΓͯstruct΍enumͰ΋Ͱ͖ΔΑ͏ʹͳͬͨ ‣ ࢀরܕ͕ඞཁ΍JTBܧঝ͕ඞཁͳ৔߹͸ࠓ·Ͱ௨ΓclassͰ ‣ ஋ܕ͕͍͍৔߹͸struct΍enumͰ ‣ DBOEP४ڌ͸protocolͰ