Swift
Swift2

protocol の extension の利用例を思いついた

More than 1 year has passed since last update.

あるコンテナのキャッシュのためにDictionaryを使っていたとき、

できるだけI/F側がゴチャゴチャしにくい方法を考えていたら

protocol を extension することで解決できたので共有しておきます。

var dict:[String:UIView] = [:]

func fuga(key:String, view:UIView){
dict[key] = view
}

// 文字列以外がすんなり入らない。
fuga("text", view: UIView())
fuga(1, view: UIView()) // コンパイルエラー
fuga(1.2, view:UIView()) // コンパイルエラー

// こうすれば入るけど、面倒

fuga(String(1), view: UIView())
fuga(String(1.2), view:UIView())

// クラスの場合はどうしよう

class Profile {
var fistName:String
var lastName:String
var age:Int
init(first:String, last:String, age:Int){
self.fistName = first
self.lastName = last
self.age = age
}
}
fuga(Profile(first: "m", last: "k", age: 30), view:UIView()) // コンパイルエラー


Stringを返させるプロトコルにする

protocol Key {

var Name:String { get }
}
func hoge(key:Key, view:UIView){
dict[key.Name] = view
}

// プロトコルを採用したものじゃないといけなくなったので、文字列よりひどくなる
hoge("text", view: UIView()) // コンパイルエラー
hoge(1, view: UIView()) // コンパイルエラー
hoge(1.2, view:UIView()) // コンパイルエラー
hoge(Profile(first: "m", last: "k", age: 30), view:UIView()) // コンパイルエラー


protocol extension を使って、String,Int,Doubleといったプリミティブ型を始めクラスのデフォルト行動を定義する

extension String : Key{

var Name: String{get{return self}}
}
extension Int : Key{
var Name: String{get{return String(self)}}
}
extension Double : Key{
var Name: String{get{return String(self)}}
}
extension Profile : Key{
var Name: String{get{return String("\(self.fistName)\(self.lastName)\(self.age)")}}
}
// これなら通る
hoge("text", view: UIView())
hoge(1, view: UIView())
hoge(1.2, view:UIView())
hoge(Profile(first: "m", last: "k", age: 30), view:UIView())