Skip to content

Instantly share code, notes, and snippets.

@wm3
Created November 13, 2016 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wm3/2ed3be73abbab8aa948de7358bf704a6 to your computer and use it in GitHub Desktop.
Save wm3/2ed3be73abbab8aa948de7358bf704a6 to your computer and use it in GitHub Desktop.
クラスメソッドを抽象メソッド化できると嬉しいと思う使い方
//
// Swift で例を挙げてみる。
//
// 例: JSON が与えられたら適宜クラスを選択してデコードする処理
//
// [
// { "type": "user", "id": "12345", "name": "wm3" },
// { "type": "post", "userId": "12345", "content": "今日こそ早く寝るぞ!😤" }
// ]
//
// みたいな JSON をマップの配列として持っているとする。
// これをオブジェクトにデコードするための仕組みが欲しい。
//
let input = [
[ "type": "user", "id": "12345", "name": "wm3" ],
[ "type": "post", "userId": "12345", "content": "今日こそ早く寝るぞ!😤" ]
]
//
// そこで、static な decode メソッドを必須とするインタフェースを作る。
//
protocol Decodable {
static func decode(_ map: [String: String]) -> Self
}
//
// デコードしたいクラスに static な decode メソッドを実装する。
//
struct User: Decodable {
let id: String
let name: String
static func decode(_ map: [String: String]) -> User {
return User(id: map["id"]!, name: map["name"]!)
}
}
struct Post: Decodable {
let userId: String
let content: String
static func decode(_ map: [String: String]) -> Post {
return Post(userId: map["userId"]!, content: map["content"]!)
}
}
//
// 上のデコード可能なクラスを名前と一緒に登録しておく。
//
let decodables: [String: Decodable.Type] = [
"user": User.self,
"post": Post.self
]
//
// 入力を受け取る時、それらをデコードして標準出力にダンプする。
// デコードするクラスは "type" 属性を元に適切なクラスを判別している。
//
for entry in input {
let decoded = decodables[entry["type"]!]!.decode(entry)
dump(decoded)
}
//
// 結果はこんな感じ。
//
// ▿ x.User
// - id: "12345"
// - name: "wm3"
// ▿ x.Post
// - userId: "12345"
// - content: "今日こそ早く寝るぞ!😤"
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment