EZ-‐‑‒NET  熊⾕谷友宏  
http://ez-‐‑‒net.jp/
Swift 2.0
2015.07.07  
@  WWDC2015  情報共有会
プロトコル拡張の話?
熊谷友宏
EZ-NET http://ez-net.jp/
@es_kumagai
Xcode 5 徹底解説
IP Phone 音でダイヤル 音で再配達ゴッド
いつもの電卓
with 割勘ウォッチ
MOSA
#yidev
横浜 iPhone 開発者勉強会
熊谷友宏
EZ-NET http://ez-net.jp/
@es_kumagai
次回は 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 飼い主が犬を操縦する
手続き型っぽい?
お⼿手!
おすわり!
待て!
吠えろ
くるっと回らせよう
ご飯を与えて噛ませる
プロトコル指向
これからの話?
柴⽝犬
型には最低限の機能  
だけを揃える
⾁肉⾷食型
⾛走れる
歩ける
雑⾷食性
型を特徴で説明する
プロトコルで特徴を表現
吠え
れる
⽝犬型
プロトコル指向
これからの話?
柴⽝犬
⾁肉⾷食型
⾛走れる
歩ける
吠え
れる
雑⾷食性
吠えさせる ⾛走らせる
⽌止まらせる⾁肉を与える
特徴に応じた機能を える
ジェネリック関数
型には最低限の機能  
だけを揃える
⽝犬型
プロトコル指向
これからの話?
吠えさせる ⾛走らせる
⽌止まらせる⾁肉を与える
特徴から機能を選ぶ
関数型っぽい?
⼩小太郎郎柴⽝犬
⾁肉⾷食型
⾛走れる
吠え
れる
雑⾷食性
なにを

させよう?
柴⽝犬
吠え
れる
⽝犬型
プロトコル指向
さらにこれから
⾁肉⾷食型
⾛走れる
歩ける
雑⾷食性
型には最低限の機能  
だけを揃える
吠えさせる ⾛走らせる
⽌止まらせる⾁肉を与える
柴⽝犬
吠え
れる
⽝犬型
プロトコル指向
さらにこれから
⾁肉⾷食型
⾛走れる
歩ける
雑⾷食性
特徴に機能を関連付ける
プロトコル拡張
吠えさせる
⾛走らせる
⽌止まらせる
⾁肉を与える
型には最低限の機能  
だけを揃える
柴⽝犬
⽝犬型
プロトコル指向
さらにこれから
吠え
れる⾁肉⾷食型
⾛走れる
歩ける
雑⾷食性
さらに歩けて吠えれるなら…
柴⽝犬
⽝犬型
プロトコル指向
さらにこれから
特徴に着目して機能を作る
条件付きプロトコル拡張
『三回まわってワン!』
さらに歩けて吠えれるなら…
右回りで歩かせて…
右回りで歩かせて…
右回りで歩かせて…
吠えさせる
〓
かわいさ作りに_̲

専念念できる_̲_̲
こんなところが
プロトコルの醍醐味かも
プロトコル拡張の話?
おしまい
▶ プロトコル拡張
✴ プロトコルを拡張する機能
✴ 既定の実装を添えられる
✴ 条件で縛った実装が可能
✴ プロトコルでも型でも縛れる
✴ 既定の実装は上書きできる
▶ プロトコルの醍醐味
✴ 特徴を寄せ集めて型を作る
✴ 特徴に着目したプログラミング

プロトコル拡張の話? #WWDC21cafe