-- Views
August 30, 16
スライド概要
Swift 3 は、ガイドラインを知っておくと変化がとっても掴みやすくなる印象。そう思って、そんな辺りについてざっくり見渡せるように資料にまとめておくことにしました。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 11,241 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
4XJGU Λॻ͘ͱ͖ʹ͓͖͍ͬͯͨ "1*%FTJHO(VJEFMJOFT ",*#"TXJGUº4XJGUѪձPO &;/&5۽୩༑ IUUQF[OFUKQ 4XJGU%FWFMPQFS1SFWJFX
ૉఢͳ"1*Λɺॻ͖·͠ΐ͏ CZ4XJGU"1*%FTJHO(VJEFMJOFT
۽୩༑ 5PNPIJSP,VNBHBJ ⾣ 4XJGU͕ޠݴେ͖Ͱ͢ʂ ⾣ ΈΜͳͰָ͠Ήษڧձ͕େ͖Ͱ͢ʂ ⾣ ϓϩάϥϛϯάͷָ͠͞Λ͍͖͍͑ͯͨɻ !FT@LVNBHBJ UPNPIJSPLVNBHBJ $PEF1JFDFGPSNBD04 IUUQF[OFUKQ 9DPEFపఈղઆ
UI"VHVTU
話してきました IUUQTJPTEDKQDOPEF NJO
ษڧձΛ։࠵͍ͯ͠·͢ɻ Θ͍Θ͍ɺָ͘͠ɺ ΈΜͳͰޠΒ͑ΔॴΛࢦͯ͠ɻ ԣJ1IPOF։ൃऀษڧձ ΧδϡΞϧ4XJGUษڧձ ZJEFW ˏԣɾഅंಓ DTXJGU !ԣɾ੨༿ ୈճ݄ͷ։࠵ʢඪʣ ୈճΛ݄̏̕ʹ։࠵ IUUQTBUOEPSHHSPVQTZJEFW IUUQTBUOEPSHHSPVQTDTXJGU
͏ͻͱͭɺษڧձΛ࢝Ί·͢ʂ 4XJGUͷૅجΛΈΜͳͱ෮श͍ͨ͠ɻ ͜Ε͔Β࢝ΊΔਓͱ্ͱऀڃҰॹʹɻ ΈΜͳͰ4XJGU ෮शձ NJOOB@EF@TXJGU ˏौ୩ ୈճΛ݄ʹ։࠵ IUUQDTXJGUDPOOQBTTDPN
ωοτϥδΦ Ќ์ૹ։࢝ ϓϩάϥϛϯά͕େ͖ͳ̎ਓͰɺ ϓϩάϥϜޠָ͍ͯͭ͘͠ʹޠݴΒ͏൪ NPPLNPPLSBEJP Ќ൛ ۽୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ͔Β ௌ͑ͯ͘͜ΔʹࣖΛָ͚ͯ͠ΉϥδΦ IUUQNPPLNPPLSBEJPDPNB
4XJGU XJMMCFSFMFBTFETPNFUJNFJOMBUF
4XJGU%FWFMPQFS1SFWJFX IBTCFFOSFMFBTFEPO"VHVTU
4XJGU"1*%FTJHO(VJEFMJOFT IUUQTTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFT
લճͷ4XJGUѪձ 4XJGU໋໊نଇͷมߋʹ ؔ৺͕͋Δਓ͕ଟ͍ҹͩͬͨ
ࠓճͷඪ 4XJGUͷഁյతมߋͷࠜݯ 4XJGU"1*%FTJHO(VJEFMJOFTΛΔ
4XJGU"1*%FTJHO(VJEFMJOFT 4XJGU"1*%FTJHO(VJEFMJOFT ⾣ ૉΒ͍͠"1*Λॻͨ͘Ίͷࢦ ⾣ 4XJGU͜Εʹै͏ ⾣ Δͱ4XJGU͕ॻ͖͘͢ͳΔ
4XJGU"1*%FTJHO(VJEFMJOFT ॻ͔Ε͍ͯΔ͜ͱ ⾣ جຊݪଇ 'VOEBNFOUBMT ͜Μͳ͜ͱʹ৺͕͚ͯॻ͖·͠ΐ͏ ⾣ ໋໊نଇ /BNJOH ͜Μͳ໊લΛ͚ͭ·͠ΐ͏ ⾣ ׳श $POWFOUJPOT ී௨͜Μͳ;͏ʹॻ͖·͢Α ⾣ ಛผͳѻ͍ 4QFDJBM*OTUSVDUJPOT ͜Μͳͱ͖͜͏͠·͢Α
4XJGU"1*%FTJHO(VJEFMJOFT େࣄͳ͜ͱ ΨΠυϥΠϯ ݪଇͰ͋Γɺઈର Ͱͳ͍
4XJGU"1*Λॻ্͘Ͱ ͓͖͍ͬͯͨͱ͜ΖΛհ
جຊݪଇ
جຊݪଇ ͜Ε·Ͱͱɺ͜Ε͔Β 4XJGU pointer.assignFrom(source, count: 100) ⾣ ⾣ ୈ̍ҾͱͷؔΛɺ໊ؔͰઆ໌͍ͯͨ͠ ୈ̍Ҿͷϥϕϧ໊ɺطఆͰলུ͢ΔΑ͏ʹͳΔ 4XJGU pointer.assign(from: source, count: 100) ⾣ ⾣ ୈ̍Ҿͱͷؔɺϥϕϧ໊Ͱઆ໌͢Δ ୈ̍Ҿͷϥϕϧ໊ɺطఆͰ໌͕هඞཁʹͳΔ
جຊݪଇ ࣍ ӳจͱͯࣗ͠વʹಡΊΔΑ͏ʹ Ͱܕͳ͘ɺׂͰ໊લΛ͚ͭΔ ෆඞཁͳ۟ޠলུ͢Δ ͯ͢ͷ͔۟ޠΒᐆດੑΛআ͘ ҾϥϕϧʹલஔࢺΛؚΊͳ͍߹ ද͖͠ݱΕͳ͍࣌ɺϥϕϧ໊Ͱิ ෭࣍తͳҾͰɺӳจ๏͍ͳ͠ʹؾ ઐ༻ޠͷ༻ɺۃݟΊ͕ඞཁ
جຊݪଇ ӳจͱͯࣗ͠વʹಡΊΔΑ͏ʹ ⾣ ༻࣌ʹɺӳจͷΑ͏ʹಡΊΔΑ͏ʹ͢Δ // album, insert photo at current page. album.insert(photo, at: currentPage) // album's photos remove all keeping capacity. album.photos.removeAll(keepingCapacity: true) // album, insert photo page current page. album.insert(photo, page: currentPage) // album's photos remove all capacity. album.photos.removeAll(capacity: true)
جຊݪଇ Ͱܕͳ͘ɺׂͰ໊લΛ͚ͭΔ ⾣ ҾมɺଐܕɺׂͰ໊લΛ͚ͭΔ ⾣ ʹ໊ܕԊ໊ͬͨલɺ໌ྎ͞දྗݱΛଛͳ͏ // 要素の配列 から位置 x に該当するものを消す。 associatedtype ContentView : UIView func suffix(from start: Index) -> SubSequence // 完全に役目を汲み取れなくなる例 associatedtype ViewType : UIView // 型寄りの index よりは、役割寄りの start が明瞭な例 func suffix(from index: Index) -> SubSequence
جຊݪଇ ෆඞཁͳ۟ޠলུ͢Δ ⾣ આ໌͕ͳͯ͘໌Β͔ͳ໊લɺল͘ ⾣ ൚༻తͳ໊લͷొ͛Δ // 要素の配列 から、要素 x を消す。 elements.remove(x) // 要素型の x であれば“要素である”ことは自明 elements.removeElement(x) // デバイスの配列 で“element”という言葉は不適切 devices.removeElement(device) // デバイスの配列 から、デバイスを消す。 devices.remove(device)
جຊݪଇ ͯ͢ͷ͔۟ޠΒᐆດੑΛআ͘ ⾣ ۟ޠͷҙຯ͕ϒϨͳ͍Α͏ʹ͢Δ ⾣ ͦΕΛফ͍ͨ͠ͷ͔ɺͦ͜ʹ͋ΔͷΛফ͍ͨ͠ͷ͔ // 要素の配列 から位置 x に該当するものを消す。 elements.remove(at: index) // 要素の配列 から、要素 y を消す。 elements.remove(y) 1PJOU લऀɺফ͍ͨ͠ͷYͰͳ͘FMFNFOUT<Y>ͷཁૉͰ͋Δ ⾣ ऀޙɺมZ͕&MFNFOUͳܕΒlཁૉZzͱಡΊΔ ⾣ ҐஔΛࣔ͢ҾɺલஔࢺQSFQPTJUJPOQISBTFͰද͢ݱΔ ⾣
جຊݪଇ ҾϥϕϧʹલஔࢺΛؚΊͳ͍߹ ⾣ ࠷ॳͷҾ͚ͩͰҐஔΛࣔ͢ͳΒɺϥϕϧ໊ʹॻ͘ ⾣ ෳͷҾͰҐஔΛࣔ͢ͳΒɺ໊ؔʹॻ͘ // 記録から、位置 x に該当する値を取得。 records.value(at: x) // 記録から、列 y 行 z に該当する値を取得。 records.valueAt(row: y, column: z) // 複数で構成時、ラベルに入れるとバランスが悪い。 records.value(atRow: y, column: z)
جຊݪଇ ද͖͠ݱΕͳ͍࣌ɺϥϕϧ໊Ͱิ ⾣ ҙຯ͕ෆͨ͠Βɺϥϕϧ໊໊ؔͰิ͢Δ ⾣ ൚༻ܕ/40CKFDU "OZ 4USJOH *OUͳͲͰ͜ىΓಘΔ // 指定したキーに対する値を更新する。 func updateValue(_ value: Any, forKey key: String) // 名前で補足しないと、使用時に意味が汲み取れない。 updateValue(100, forKey: "A") update(100, for: "A") 1PJOU ܕҾଐͰܕɺܕଋറ͕ऑ͚Εಉ༷ ⾣ ୈ̍Ҿͷ߹Ͱϥϕϧͳ͠ͷ߹ɺ໊ؔͰઆ໌͢Δ ⾣
جຊݪଇ ෭࣍తͳҾͰɺӳจ๏͍ͳ͠ʹؾ ⾣ ओతͰͳ͍ҾɺจষʹͳΒͳͯ͘ྑ͍ ⾣ ͦΕΒҰൠʹɺୈ̎Ҿୈ̏ҾҎ߱ʹஔ͔ΕΔ // 主目的はメッセージの表示。第2引数以降は副次的。 func print(_ items: Any..., separator: String, terminator: String, to output: inout Target)
جຊݪଇ ઐ༻ޠͷ༻ɺۃݟΊ͕ඞཁ ⾣ ୭ͰΔݴ༿͕͋ΔͳΒɺͦΕΛ͏ ⾣ ઐ༻ޠɺͦͷݴ༿Ͱͳ͍ͱҙຯΛଛͳ͏ͱ͖ʹ͏ // 電子計算機の分野で、正弦関数 sin は適切な共通認識。 let answer = sin(1.5) // 言葉を適切に把握してないと、何が起こるか判らない。 rinoa.junctioned(to: Bahamut.self).megaFlare() 1PJOU ུޠઐ༻ޠͷ͏ͪʢ.#1ͳͲʣ ⾣ ରͰڞ௨ೝ͕ࣝظͰ͖Δઐ༻ޠɺΉ͠Ζ·͍͠ ⾣ ແҋʹ1PLÉNPOΛ࣋ͪग़͢ͷɺΨΠυϥΠϯʹ͢Δʁ ⾣
͍ͨ͠ʹؾͷɺલஔࢺͷѻ͍ ӳจΈ͍ͨʹಡΊΔ͜ͱҙࣝͯ͠ॻ͘
ίϝϯτΛॻ͘
ίϝϯτΛॻ͘ ࣍ ॻ͘աఔͰ"1*͕ચ࿅͞ΕΔ ֓ཁઆ໌ͷॻ͖ํ w ؔlԿΛͯ͠ɺԿΛฦ͢zͷ͔ w ఴࣈlԿʹΞΫηε͢Δzͷ͔ w ΠχγϟϥΠβʔlԿΛ࡞Δzͷ͔ w ͦΕҎ֎lͦΕͬͯԿzͳͷ͔ ඞཁͰ͋Εɺଓ͚ͯৄࡉΛॻ͘ ϓϩύςΟʔͰ0 Ҏ֎໌͢هΔ
ίϝϯτΛॻ͘ ॻ͘աఔͰ"1*͕ચ࿅͞ΕΔ ⾣ ͯ͢ͷఆٛʹυΩϡϝϯτίϝϯτΛॻ͜͏ ⾣ ֓ཁઆ໌Λ̍จͰॻ͖ɺඞཁͳΒৄࡉઆ໌ॻ͘ /// Inserts a new element /// into the collection at the specified index. func insert(_ newElement: _Element, at i: Index) 1PJOU આ໌ͦͷ··ͷྲྀΕͰ"1*͕ද͍͖ͯͰݱΔ͔ ⾣ ͍͍ͨͯɺ֓ཁͱఆٛͰ͡Ύ͏ͿΜઆ໌͕ͭ͘ ⾣ ؆୯ͳݴ༿Ͱઆ໌Ͱ͖ͳ͍ͳΒ"1*σβΠϯΛٙͬͯΈΔ ⾣
ίϝϯτΛॻ͘ ֓ཁઆ໌ͷॻ͖ํ ؔlԿΛͯ͠ɺԿΛฦ͢zͷ͔ %PFTTPNFUIJOHBOESFUVSOTTPNFUIJOH ఴࣈlԿʹΞΫηε͢Δzͷ͔ "DDFTTFTTPNFUIJOH ΠχγϟϥΠβʔlԿΛ࡞Δzͷ͔ $SFBUFTTPNFUIJOH ͦΕҎ֎lͦΕͬͯԿzͳͷ͔ 4PNFUIJOH
ίϝϯτΛॻ͘㲊֓ཁઆ໌ͷॻ͖ํ ؔlԿΛͯ͠ɺԿΛฦ͢zͷ͔ ⾣ ͲΜͳ࡞༻͔ͱɺͲΜͳΓ͔Λॻ͘ ⾣ ࡞༻Γʹ͍ͭͯɺແ͍ͷॻ͔ͳ͍ /// Advances to the next element and returns it, /// or `nil` if no next element mutating func next() -> Element? /// Returns a new string by concatenating the /// elements of the sequence, adding the given /// separator between each element. func joined(separator: String = default) -> String
ίϝϯτΛॻ͘㲊֓ཁઆ໌ͷॻ͖ํ
ఴࣈlԿʹΞΫηε͢Δzͷ͔
⾣ ఴࣈͰԿʹΞΫηε͢Δ͔Λॻ͘
⾣ "DDFTTFTʜͰॻ͖͡ΊΔͷ͕Ұൠత
/// Accesses the code unit at the given position.
subscript(position: Index) -> CodeUnit { get }
ίϝϯτΛॻ͘㲊֓ཁઆ໌ͷॻ͖ํ ΠχγϟϥΠβʔlԿΛ࡞Δzͷ͔ ⾣ ͲΜͳΠϯελϯεΛੜ͢Δ͔Λॻ͘ ⾣ $SFBUFTʜͰॻ͖͡ΊΔͷ͕Ұൠత /// Creates a view of the given string. init(_ text: String)
ίϝϯτΛॻ͘㲊֓ཁઆ໌ͷॻ͖ํ ͦΕҎ֎lͦΕͬͯԿzͳͷ͔ ⾣ ؔɾఴࣈɾΠχγϟϥΠβʔҎ֎ͦΕ͕Կ͔Λॻ͘ ⾣ ܕlͲΜͳܕz͔ɺϓϩύςΟʔlͲΜͳz͔ /// A raw pointer for accessing untyped data. struct UnsafeMutableRawPointer { … } /// A textual representation of the range. var description: String { get } /// Access the `Pointee` instance referenced by `self`. var pointee: Pointee { get }
ίϝϯτΛॻ͘ ඞཁͰ͋Εɺଓ͚ͯৄࡉΛॻ͘ ⾣ ඞཁʹԠͯ͡ɺ֓ཁͷࡉৄ͚ͯ͋ߦ̍ʹޙΛॻ͘ ⾣ 4ZNCPM%PDVNFOUBUJPO.BSLVQΛ͏ /// Creates a new value, rounded to the closest /// possible representatation. /// /// If two representable values are equally close, /// the result is the value with more trailing /// zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert /// to a floating-point value. init(_ v: Int8)
ίϝϯτΛॻ͘ ϓϩύςΟʔͰ0 Ҏ֎໌͢هΔ ⾣ ෳࡶͳࢉܭΛߦ͏ϓϩύςΟʔɺෳࡶ͞Λ໌͢هΔ ⾣ ϓϩύςΟʔࢀর0 ͱࢥ͍ࠐ·Ε͕ͪ /// Returns the number of elements. /// /// - Complexity: O(1) if `Self` conforms /// to `RandomAccessCollection`; O(N) otherwise. var count: IndexDistance { get } 1PJOU ෳࡶ͕͞0 ͷ߹ɺ໌͢هΔͱࢀߟʹ͍͢͠ ⾣ ΠχγϟϥΠβʔؔɺෳࡶ͞ͷ໌͕͋هΔͱྑ͍ ⾣
4ZNCPM%PDVNFOUBUJPO.BSLVQ
ίϝϯτΛॻ͘㲊4ZNCPM%PDVNFOUBUJPO.BSLVQ ֓ཁ ⾣ આ໌ʹҙຯ͚ͮͰ͖ΔϚʔΫΞοϓޠݴ ⾣ Ͱॻ͖࢝ΊɺΩʔϫʔυͰҙຯΛఴ͑Δ /// Creates a new value, rounded to the closest /// possible representatation. /// /// If two representable values are equally close, /// the result is the value with more trailing /// zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert /// to a floating-point value. init(_ v: Int8)
ίϝϯτΛॻ͘㲊4ZNCPM%PDVNFOUBUJPO.BSLVQ ޮՌ ⾣ ΫΠοΫϔϧϓͰݟ͘͢දࣔ͞ΕΔ ⾣ "1*Λ͏ଆʹͱ͍ͬͯ͠خ let f = Double.init(_:) as (Int8) -> Double
ίϝϯτΛॻ͘㲊4ZNCPM%PDVNFOUBUJPO.BSLVQ ৄࡉ ⾣ Ҏલʹ·ͱΊͨࢿྉͪ͜Β IUUQXXXTMJEFTIBSFOFUUPNPIJSPLVNBHBJTXJGU
ίϝϯτ"1*Λચ࿅͢Δ ॻ͘ͷΛઌૹΓ͠ͳ͍
໊લ͚ͷ׳श
໊લ͚ͷ׳श ࣍ ໊ܕม໊ͷ͚ํ ໊ؔࣗͷӨʹڹΑͬͯมΘΔ ਅِΛఆ͢Δϝιου໊ͷ͚ํ ϑΝΫτϦʔϝιουͷ׳श ΠχγϟϥΠβʔͷ׳श ྻ໊ࢠڍখจࣈ͔Β࢝ΊΔ ϓϩτίϧ໊ͷ͚ํ ϓϩτίϧΛଐ͖ͱ͏Ͱܕͷ׳श
໊લ͚ͷ׳श ໊ܕม໊ͷ͚ํ ⾣ Ұൠʹɺ໊લ໊ࢺͰ͚ͭΔ ⾣ ਅِΛද͢ϓϩύςΟʔ໊ɺରͷओுͰද͢ݱΔ // 型は名詞で名前をつける。 struct ObjectIdentifier { … } // 変数名は名詞でつける。 let identifier = ObjectIdentifier(object) // 真偽値プロパティーは主張重視。配列が空であるか。 items.isEmpty
໊લ͚ͷ׳श ໊ؔࣗͷӨʹڹΑͬͯมΘΔ ⾣ ࣗͷӨ͕͋ڹΔ͔Ͱɺ໊લΛม͑Δ ⾣ ໊લ໊͕ࢺ͔ܥಈࢺͰ͔ܥɺ໋໊ํ๏͕มΘΔ // 名詞系で、自身に影響しない場合は、名詞そのまま。 let answer = value.squareRoot() // 名詞系で、自身に影響する場合は“form”接頭辞。 value.formSquareRoot() // 動詞系で、自身に影響ないなら“-ed”か“-ing”接尾辞。 let answer = value.divided(by: 3) // 動詞系で、自身に影響するなら、動詞そのまま。 value.divide(by: 3)
໊લ͚ͷ׳श ਅِΛఆ͢Δϝιου໊ͷ͚ํ ⾣ ରͷओுͱͯ͠ΈऔΕΔ໊લʹ͢Δ ⾣ ී௨ͷϝιουͱผͷنଇͰ໊લΛ͚ͭΔ // 範囲が、ある範囲と、重なる点があるか if range1.overlaps(range2) { … } // 配列が、要素を、含んでいるか if items.contains(item) { … } // 要素を返してるのか、要素を含むか判定してるのか。 let answer = items.contained(item) { … }
໊લ͚ͷ׳श ϑΝΫτϦʔϝιουͷ׳श ⾣ ಄ࣙlNBLFzͰࣔࠦ͠ɺଓ͚ͯ࡞ΔͷΛ໌͢هΔ ⾣ Ұൠʹϥϕϧ໊লུͤͣɺӳจ๏ʹ߆ΘΒͳ͍ // 内容を列挙するイテレーターを作る。 func makeIterator() -> Iterator // ボタンを作る。表題を受け取る。 func makeButton(caption: String) -> NSButton // ラベル名の英文的な流れは気にしない func makeButton(havingCaption: String) -> NSButton
໊લ͚ͷ׳श ΠχγϟϥΠβʔͷ׳श ⾣ ಉ͡Λද͢ݱΔͳΒɺ࠷ॳͷϥϕϧΛলུ͢Δ ⾣ Ճ࠶ղऍΛ͏ͳΒɺ࠷ॳͷϥϕϧΛলུ͠ͳ͍ // 同じ値を表現する場合は、素直な型変換を表現する。 let value = Int32(value64) // 再解釈を伴うなら、何が起こるかラベルで示唆する。 let value : Int32(truncatingBitPattern: value64) 1PJOU ୈ̍Ҿʹϥϕϧ͕͋Δ͔Ͱɺૉͳม͔ɺՃ͔͕Δ ⾣ ୈ̎ҾҎ߱ɺͲͪΒͷ߹ϥϕϧΛ࣋ͭͷ͕Ұൠత ⾣ ϥϕϧ໊ӳจ๏ʹ߆ΘΒͳ͍ʜ$PMPS SFES HSFFOH CMVFC ⾣
໊લ͚ͷ׳श ྻ໊ࢠڍখจࣈ͔Β࢝ΊΔ ⾣ -PXFS$BNFM$BTFͰ໊લΛ͚ͭΔ // 列挙子の名前は小文字で始める。 enum UnicodeDecodingResult { case scalarValue(UnicodeScalar) case emptyInput case error } 1PJOU 4XJGUͰ6QQFS$BNFM$BTFͩͬͨ ⾣ ྻͱ໊ࢠڍɺΛུͨ͠4USJOHͷ3BX࿈ಈ͢ΔͷͰҙ ⾣ 6QQFS$BNFM$BTFͰ໊͚Δͷɺͱ໊ܕϓϩτίϧ໊͚ͩ ⾣
໊લ͚ͷ׳श ϓϩτίϧ໊ͷ͚ํ ⾣ ۩ମతͳԿ͔Λද͢ͳΒɺ໊ࢺͰ͚ͭΔ ⾣ ੑ࣭తͳͷͳΒɺඌࣙlBCMFzlJOHzΛ͚ͭΔ // 具体的に“コレクション”を表現するので、名詞。 protocol Collection { … } // 比較可能性を表現するので、接尾辞“-able”な名前。 protocol Comparable { … } 1PJOU ׂతͳ໊લʹɺඌࣙl1SPUPDPMzΛ͚ͭΔ߹͕͋Δ ⾣ ΨΠυϥΠϯతʹɺඌࣙl1SPUPDPMzΛ͚ͭΔنఆͳ͍ ⾣
໊લ͚ͷ׳श ϓϩτίϧΛଐ͖ͱ͏Ͱܕͷ׳श ⾣ ໊শͱׂ͕ಉ͡ͳΒɺඌࣙ5ZQFͰিಥճආ͢Δ ⾣ ඪ४Ͱɺଐʹ໊ܕඌࣙ1SPUPDPM͕ओྲྀʁ // プロトコル名が役割と一致するなら、名称に Type を付与 associatedtype IteratorType : Iterator // ただし、標準ではプロトコル名に Protocol が主流 associatedtype Iterator : IteratorProtocol 2VFTUJPO લऀɺੑ࣭Λද͢ݱΔϓϩτίϧଆʹl5ZQFzΛఴ͍͑ͨҹ ⾣ ऀޙɺར༻໊Λݟӽͯ͠ϓϩτίϧ໊ΛܾΊΔͷɺࠅͳҹ ⾣ ඪ४ϥΠϒϥϦ͕ɺΨΠυϥΠϯͱໃ६͍ͯ͠Δҹ ⾣
׳शΛΕɺॻ͖͘͢ͳΔ ӳจΛҙࣝ͢ΕɺͳΜͱͳ͘௫Ίͦ͏
ఆٛΛͬͱચ࿅͢Δ
ఆٛΛͬͱચ࿅͢Δ ࣍ ҧ͏ػೳʹಉ໊͡લΛΘͳ͍ طఆͰɺؔ࿈ੑΛද͖ͰݱΔ Γ͚ͩͰͷPWFSMPBE͠ͳ͍ େҬؔΑΓϝιουΛ͏ ҙຯͷͳ͍ϥϕϧ໊লུ͢Δ δΣωϦοΫಛ༗ͷᐆດੑʹҙ
ఆٛΛͬͱચ࿅͢Δ ҧ͏ػೳʹಉ໊͡લΛΘͳ͍ ⾣ جຊతͳҙຯ߹͍͕ಉ͡ͱ͖ɺجຊ໊Λڞ༗͢Δ ⾣ ॴଐΛ͛ލɺҟͳΔҙຯʹͬͯྑ͍ // 同じ所属で、違う意味で基本名を共有している。 class Database { func index() func index(of row: Row) -> Int } // 索引の再構築 // 行番号の取得 // 所属外とは干渉しない。所属内では同じ意味。 struct Bookshelf { func index(_ i: Int, offsetBy n: Int) -> Int { … } func index(after i: Int) -> Int { … } }
ఆٛΛͬͱચ࿅͢Δ طఆͰɺؔ࿈ੑΛද͖ͰݱΔ ⾣ طఆͰද͖ͰݱΔͳΒɺ0WFSMPBEΘͳ͍ ⾣ ಉͷػೳ͔Ͳ͏͔ɺ໌ྎʹͳΔ // これらの機能は、関連している? struct String { init(_ value: Int) { … } init(_ value: Int, radix Int) { … } } // 既定値を使えば、関連性を気にする必要さえない。 struct String { init(_ value: Int, radix Int = 10) { … } }
ఆٛΛͬͱચ࿅͢Δ Γ͚ͩͰͷPWFSMPBE͠ͳ͍ ⾣ ໊લ͕ಉ͡ͰɺΓ͕ҧ͏ػೳΛ࡞ΕΔ͕ʜ ⾣ ܕਪͰᐆດʹͳΔͨΊɺ༻͠ͳ͍ // 指定したキーに対する値を更新する。 struct Variant { func value() -> Int func value() -> Double } *NQSFTTJPO ݸਓతʹBTͰεϚʔτʹΓସ͑ΒΕΔͷ͕Έͩͬͨ ⾣ VOTBGF#JU$BTUɺҾͰlΓͷܕzΛड͚औΔ࡞Γ ⾣
ఆٛΛͬͱચ࿅͢Δ
େҬؔΑΓϝιουΛ͏
⾣ ϝιουͳΒɺॴଐͰҙຯ͕໌ྎʹͳΔ
⾣ ॴଐ͕ͳ͍ͱ͖׳शతʹదͳΒɺେҬؔΛ͏
// 配列の並び替えた値、と表現できる。
struct Array<Element> {
func sorted() -> Array<Element> { … }
}
// 所属が定まらない場合に、大域関数として扱う。
func max(_ x: Int, _ y: Int, _ z: Int)
// 数値の絶対値、所属はあっても abs(x) が慣習的。
func abs(_ x: Int) -> Int
ఆٛΛͬͱચ࿅͢Δ ҙຯͷͳ͍ϥϕϧ໊লུ͢Δ ⾣ ϥϕϧ໊ʹҙຯ͕ͳ͚Εলུ͢Δ ⾣ ؔΛ͏ࢹʹཱͭͱɺஅ͍͢͠ // もはや x, y, z は、どうでもいい。 let answer = max(x: 3, y: 5, z: 2) // 慣習的に abs(x) な書き方が自然。 let answer = abs(value: -30) 1PJOU ҾΛରʹѻ͏ؔͰɺϥϕϧ໊͕ෆཁʹͳΔ ⾣ ϥϕϧ͕ͳͯ͘ɺ׳शతʹҙຯ͕Θ͔Δ߹ಉ༷ ⾣
ఆٛΛͬͱચ࿅͢Δ
δΣωϦοΫಛ༗ͷᐆດੑʹҙ
⾣ ܕҾ͕ܾ·ͬͨͰޙɺᐆດʹͳΔ͜ͱ͕͋Δ
// Element = Any で束縛すると…
struct Array<Element> {
// element に [Any] が渡せる。
mutating func append(_ element: Element) { … }
// elements に [Any] が渡せる。
}
mutating func append<S:Sequence>(_ elements: S)
where S.Iterator.Element == Element { … }
1PJOU
ʹऀޙϥϕϧlDPOUFOUT0GzΛ͚ͯճආ͢Δ
⾣ ҙຯతʹ"QQFOETUIFDPOUFOUTPGbFMFNFOUT`UPUIFFOE
⾣
ಡΈखʹͱͬͯ༏͍͠ίʔυʹͳΔ ׳Ε͖ͯͨΒઓ͍ͨ͠ɺ࣍ͷεςοϓ
͓·͚ ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ
ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ 4XJGUҎ͚߱ͩͰ͏ίʔυΛॻ͘ #if swift(>=3.0) // Swift 3.0 以上でコンパイルするコード #else // Swift 3.0 未満でコンパイルするコード #endif 4XJGUҎ্Ͱ͑Δ
ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ ໊ؔͷมߋΛଅ͢ 4XJGUͷॻࣜͰఆٛ // 新しい名前に変更する。 mutating func formUnion() { … } // 旧名称を定義、名前の変更を明記する。 @available(*, unavailable, renamed: "formUnion") mutating func unionInPlace() { /* 実装不要 */ }
ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ
໊ؔͷมߋΛଅ͢ʢҾΛߟྀʣ
4XJGUͷॻࣜͰఆٛ
// 新しい名前に変更する。
func advanced(by amount: Int) -> Int { … }
// 旧名称を定義、名前の変更を明記する。
@available(*, unavailable, renamed: "advanced(by:)")
func advancedBy(_ amount: Int) -> Never { /* 実装不要 */ }
ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ ϓϩτίϧ໊ͷมߋΛଅ͢ 4XJGUͷॻࣜͰఆٛ // 新しい名前に変更する。 protocol Bookshelf { … } // 旧名称を型エイリアスで定義し、新しい型を設定する。 @available(*, unavailable, renamed: "Bookshelf") typealias BookshelfType = Bookshelf
ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ ྻࢠڍͷมߋΛଅ͢ // 列挙子を、新しい名前に変更する。 enum DecodingResult { case scalarValue(UnicodeScalar) case emptyInput case error } // 列挙子は、自動で Fix-it の対象になる。
৽໊Ͱچલ͕িಥ͢Δͱ͖ʜʁ
ΨΠυϥΠϯద༻Λࢧԉ͢Δػೳ ৽໊Ͱچલ͕িಥ͢Δͱ͖ʜʁ // これを sorted に変えたい。 func sort() { … } // これを sort に変えたいが、旧 sort と衝突する。 mutating func sortInPlace() -> Cards { … }
!TXJGU@NJHSBUJPO
!TXJGU@NJHSBUJPO چఆٛʹɺ৽໊͍͠લΛଐੑͰఴ͑Δ // 旧実装はそのまま、新しい名称を指定する。 @swift3_migration(renamed="sorted()") func sort() -> Cards { … } @swift3_migration(renamed="sort()") mutating func sortInPlace() { … } 4XJGUͷॻࣜͰఆٛ
!TXJGU@NJHSBUJPO 5P-BUFTU4XJGU4ZOUBYΛ࣮ߦ͢Δ
!TXJGU@NJHSBUJPO ͦΕͧΕ͕దʹஔ͖͑ΒΕΔ ⾣ ؔچTPSU*O1MBDF͕ɺ৽ؔTPSUʹஔ͖ΘΔ ⾣ ؔچTPSU͕ɺ৽ؔTPSUFEʹஔ͖ΘΔ
ྻܕڍࣗಈϚΠάϨʔγϣϯ
!TXJGU@NJHSBUJPO ࣜܗچͷྻ͖ͱ͕ͨͬ͋ܕڍ // 何もしなくても、マイグレーションの対象になる。 enum DecodingResult { case ScalarValue(UnicodeScalar) case EmptyInput case Error } func decode(source: String?) -> DecodingResult { … } 4XJGUͷॻࣜͰఆٛ
!TXJGU@NJHSBUJPO 5P-BUFTU4XJGU4ZOUBYΛ࣮ߦ͢Δ
!TXJGU@NJHSBUJPO ྻ͕ࢠڍ-PXFS$BNFM$BTFʹͳΔ ⾣ ྻࢠڍͷఆ͕ٛɺࣗಈతʹม͞ΕΔ ⾣ ྻࢠڍΛ͍ͬͯΔՕॴɺม͞ΕΔ
·ͱΊ
4XJGU"1*%FTJHO(VJEFMJOFT ·ͱΊ ⾣ ӳจΛΠϝʔδͯ͠ॻ͖·͠ΐ͏ ⾣ Ҿϥϕϧͷ͍ํ͕ݟ͞Εͨ ⾣ ໘͝ͱͷ໋໊ํ๏͕ࣔ͞Εͨ ⾣ طଘίʔυͷӨڹൣғେ͖͍ ⾣ ౷ҰͯͰ͕ײɺಡΈ͘͢ͳΔ ⾣ ࢦ͕Ͱ͖ɺॻ͘ͱ͖ͷΈ͕ܰݮ
ૉఢͳ"1*Λɺॻ͖·͠ΐ͏
&OKPZ4XJGU 5IBOLZPV 4XJGUΛॻ͘ͱ͖ʹ͓͖͍ͬͯͨ "1*%FTJHO(VJEFMJOFT &;/&5۽୩༑ IUUQF[OFUKQ ⾣ ίϝϯτΛॻ͘ ⾣ ໊લ͚ͷجຊ ⾣ ໊લ͚ͷ׳श ⾣ ఆٛΛͬͱચ࿅͢Δ ⾣ !TXJGU@NJHSBUJPO