Skip to content

Instantly share code, notes, and snippets.

@kenmaz
Created March 29, 2016 17:59
Show Gist options
  • Save kenmaz/b618fbc0d9d8b6f32836d5d58e0e36ac to your computer and use it in GitHub Desktop.
Save kenmaz/b618fbc0d9d8b6f32836d5d58e0e36ac to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import Foundation
class Thunder { }
class Fire { }
//genericなprotocol
protocol Pokemon {
typealias PokemonType //swift2.2ではassociatedTypeって書くんだっけ
func attack(move:PokemonType) //move=わざ
}
struct Pikachu: Pokemon {
typealias PokemonType = Thunder
func attack(move: Thunder) { print("サンダー") }
}
class Raichu: Pokemon {
typealias PokemonType = Thunder
func attack(move: Thunder) { print("サンダー") }
}
class Charmander: Pokemon {
func attack(move: Fire) { print("ファイア") }
}
////////
//雷攻撃
let thunderAttack = Thunder()
//火攻撃
let fireAttack = Fire()
//==こういうのを書きたい(雷属性のポケモン配列に雷攻撃させたい)===
//let pikachu = Pikachu()
//let raichu = Raichu()
//// let pikachu:Pokemon = Pikachu() //これはNG
////ポケモンならなんでも入れられる型のobjが定義できない
//
////genericなprotocol型の配列
//let electricPokemons:[Pokemon] = [pikachu, raichu] //これもNG
//for pokemon in electricPokemons {
// pokemon.attack(thunderAttack)
//}
//////////
//こう書ける
class AnyPokemon <PokemonType>: Pokemon {
private let _attack: ((PokemonType) -> Void)
required init<U:Pokemon where U.PokemonType == PokemonType>(_ pokemon: U) {
_attack = pokemon.attack
}
func attack(type:PokemonType) {
return _attack(type)
}
}
let pikachu = AnyPokemon(Pikachu())
let raichu = AnyPokemon(Raichu())
let electricPokemons:[AnyPokemon<Thunder>] = [pikachu, raichu]
for pokemon in electricPokemons {
pokemon.attack(thunderAttack)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment