>100 Views
July 08, 15
スライド概要
2015 年の七夕の日に開催された @yucovin さん主催の「WWDC2015 情報共有会」で、Swift 2.0 で登場したプロトコル拡張 (Protocol Extension) の基本的な書き方を中心に、簡単にながらその魅力を紹介してきました。
プロトコル拡張って、機能だけ見るとそんな難しいものではなくて、それより使いどころを意識する方が大事なのかも? そう思って、新機能ではないですけれど、それを支えるそもそもの「プロトコル」というものについての特徴をさらっと整理してみて、そこのどこに今回のプロトコル拡張が食い込んできたのか、そんなところを雰囲気程度ですけれど、感じられるようにしてみました。プロトコル拡張に関心を持つきっかけにしてもらえたら幸いです。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 6,648 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
Swift 2.0 プロトコル拡張の話? 2015.07.07 @ WWDC2015 情報共有会 EZ-‐‑‒NET 熊⾕谷友宏 http://ez-‐‑‒net.jp/
熊谷友宏 EZ-NET http://ez-net.jp/ @es̲kumagai Xcode 5 徹底解説 MOSA IP Phone 音でダイヤル いつもの電卓 with 割勘ウォッチ 音で再配達ゴッド
熊谷友宏 EZ-NET http://ez-net.jp/ @es̲kumagai #yidev 横浜 iPhone 開発者勉強会 次回は 7月11日に開催 https://atnd.org/events/67499
プロトコル拡張とは?
プロトコルを拡張する機能 Swift 2.0 で新登場
たとえば
こんなプロトコルがあったとき protocol CollectionType : SequenceType { typealias Generator : GeneratorType typealias Index : ForwardIndexType subscript(index:Index) -> Generator.Element { get } } var startIndex:Index { get } var endIndex:Index { get } protocol GeneratorType { } typealias Element
プロトコル拡張の基本
既定の実装を追加 extension CollectionType { var count:Index.Distance { } } return distance( self.startIndex, self.endIndex)
既定の実装を追加 全てのコレクション型で使える let array = [Int]() let dictionary = [String:Int]() array.count dictionary.count
条件を限定して実装を追加 extension CollectionType where Generator.Element : IntegerType { var sum:Generator.Element { } } return self.reduce(0) { $0 + $1 }
条件を限定して実装を追加 条件に合致した型だけで使える let intArray = [Int]() let strArray = [String]() intArray.sum strArray.sum
細かい条件指定
複数の条件で限定
extension CollectionType where
Index : Streamable,
Generator.Element : IntegerType {
func printIndexOf<S:OutputStreamType>
(element:Generator.Element,
inout to stream:S) {
}
}
self.indexOf(element)?.writeTo(&stream)
型が同じという前提 extension CollectionType where Generator.Element : IntegerType, Index.Distance == Generator.Element { var average:Generator.Element { } return self.reduce(0) { $0 + $1 } / self.count var count:Index.Distance { } } return distance( self.startIndex, self.endIndex)
自分自身を限定する extension CollectionType where Self : Equatable, Self : NillLiteralConvertible { var isNull:Bool { } } return self == nil
型で明示的に限定 extension CollectionType where Generator.Element == String { var lastPathComponents:String { } } return self.map { $0.lastPathComponent }
既定の実装
既定の実装は上書き可能 extension CollectionType { var isEmpty:Bool { } } return self.startIndex == self.endIndex struct MyCollection : CollectionType { var isEmpty:Bool { } } return reduce(true) { $0 && $1.isEmpty }
これくらい
扱い方が大事かも?
〓 プロトコル拡張 プロトコルを拡張する機能
プロトコル 型の振る舞いを決めるもの
オブジェクト指向 ⽣生きる機能を実装 消化器・循環器・呼吸器など これまでの話 ⾷食事を⾁肉に限定 必要な機能を実装 ⽣生物 動物 ⾁肉⾷食 ⽝犬 柴⽝犬 動く機能を実装 運動神経・関節など ワンと吠える、雑⾷食性など ⽝犬らしい機能の実装 かわいく!_̲ 「ふぉとさいく」より http://410319.jp/sozai/ 機能を特化して積み上げる クラス継承
オブジェクト指向 これまでの話 おすわり! 柴⽝犬 ⼩小太郎郎 お⼿手! 待て! くるっと回らせよう 吠えろ ご飯を与えて噛ませる 2014 年年柴⽝犬名前ランキング 1 位 http://⽝犬の性格と選び⽅方.com/namerank-‐‑‒3110 飼い主が犬を操縦する 手続き型っぽい?
プロトコル指向 これからの話? ⽝犬型 吠え れる ⾁肉⾷食型 柴⽝犬 歩ける ⾛走れる 雑⾷食性 型には最低限の機能 だけを揃える 型を特徴で説明する プロトコルで特徴を表現
プロトコル指向 これからの話? ⽝犬型 吠え れる ⾁肉⾷食型 柴⽝犬 歩ける ⾛走れる 雑⾷食性 型には最低限の機能 だけを揃える 吠えさせる ⾛走らせる ⾁肉を与える ⽌止まらせる 特徴に応じた機能を揃える ジェネリック関数
プロトコル指向 これからの話? 柴⽝犬 ⼩小太郎郎 吠え れる ⾁肉⾷食型 雑⾷食性 なにを させよう? ⾛走れる 吠えさせる ⾛走らせる ⾁肉を与える ⽌止まらせる 特徴から機能を選ぶ 関数型っぽい?
プロトコル指向 さらにこれから ⽝犬型 吠え れる ⾁肉⾷食型 柴⽝犬 歩ける ⾛走れる 雑⾷食性 型には最低限の機能 だけを揃える 吠えさせる ⾛走らせる ⾁肉を与える ⽌止まらせる
プロトコル指向 さらにこれから ⽝犬型 吠え れる ⾁肉⾷食型 ⾁肉を与える 雑⾷食性 柴⽝犬 吠えさせる 歩ける ⾛走れる ⾛走らせる ⽌止まらせる 型には最低限の機能 だけを揃える 特徴に機能を関連付ける プロトコル拡張
さらに歩けて吠えれるなら… プロトコル指向 さらにこれから ⽝犬型 吠え れる ⾁肉⾷食型 柴⽝犬 雑⾷食性 ⾛走れる 歩ける
さらに歩けて吠えれるなら… プロトコル指向 さらにこれから ⽝犬型 右回りで歩かせて… 右回りで歩かせて… 柴⽝犬 右回りで歩かせて… 〓 吠えさせる 『三回まわってワン!』 かわいさ作りに_̲ 専念念できる_̲_̲ 特徴に着目して機能を作る 条件付きプロトコル拡張
こんなところが プロトコルの醍醐味かも
プロトコル拡張の話? おしまい ▶ プロトコル拡張 ✴ プロトコルを拡張する機能 ✴ 既定の実装を添えられる ✴ 条件で縛った実装が可能 ✴ プロトコルでも型でも縛れる ✴ 既定の実装は上書きできる ▶ プロトコルの醍醐味 ✴ 特徴を寄せ集めて型を作る ✴ 特徴に着目したプログラミング