2014年08月08日
Posted by 屋台ブルー at
2014年08月08日00:00 Comment(0)
Swiftで遊ぼう! - 31 プロトコールをなんとかして理解したい...
protocolは、クラスや構造体の関数(function)、メソッド(method)や初期化(initializer)のパラメーターや戻り値のタイプ(type)としての振る舞いをする。定数や変数、プロパティのタイプ(tyoe)として動くし、配列(array)やディクショナリ(dictionary)のアイテムのタイプとして働く...
じーっとコードを眺めながら考える。
protocol RandomNumberGenerator {
func random() -> Double
}
class LinearCongruentialGenerator:RandomNumberGenerator {
var lastRandom = 32.0
let m = 139968.0
let a = 3877.0
let c = 29573.0
func random() -> Double {
lastRandom = ((lastRandom * a + c) % m)
return lastRandom / m
}
}
let generator = LinearCongruentialGenerator()
println("Here's a random number: \(generator.random())")
class Dice {
let sides: Int
let generator: RandomNumberGenerator
init(sides: Int, generator:RandomNumberGenerator) {
self.sides = sides
self.generator = generator
}
func roll() -> Int {
return Int(generator.random() * Double(sides)) + 1
}
}
let sixRoll = Dice(sides:6, generator:
LinearCongruentialGenerator())
for _ in 1...15 {
println("Random dice roll is \(sixRoll.roll())")
}
Here's a random number: 0.0976580361225423
Random dice roll is 1
Random dice roll is 5
Random dice roll is 6
Random dice roll is 4
Random dice roll is 2
Random dice roll is 6
Random dice roll is 6
Random dice roll is 6
Random dice roll is 6
Random dice roll is 1
Random dice roll is 1
Random dice roll is 4
Random dice roll is 1
Random dice roll is 2
Random dice roll is 5
RandomNumberGeneratorというプロトコールを作って、これをタイプ(型:type)として使うため、というか、プロトコールはこういう風に型として使うことを目的として考えられているんでしょう。前日のようにクラスのメソッドで宣言して実装するだけなら必要のない機能になるけど、今日の例文のように、拡張して行く場合にその存在理由がはっきりしてくる。あくまでもprotocolは概念のみで何も実装されていないが、そういう概念ということは型と同様ということですよね。IntやStringのようなもんですよね。したがって、クラスDiceのプロパティの型宣言に使われているということになる。しかし、概念のみではインスタンスを生成する時に何も起こらないので、インスタンスを生成するときは、概念が形となったクラスLinearCongruentialGeneratorを引数としてDice型インスタンス生成に使用しなければんらないということだろう。自分で書いていながら混乱しているが、なんとなくプロトコールの拡張性が見えたような気がする。
じーっとコードを眺めながら考える。
protocol RandomNumberGenerator {
func random() -> Double
}
class LinearCongruentialGenerator:RandomNumberGenerator {
var lastRandom = 32.0
let m = 139968.0
let a = 3877.0
let c = 29573.0
func random() -> Double {
lastRandom = ((lastRandom * a + c) % m)
return lastRandom / m
}
}
let generator = LinearCongruentialGenerator()
println("Here's a random number: \(generator.random())")
class Dice {
let sides: Int
let generator: RandomNumberGenerator
init(sides: Int, generator:RandomNumberGenerator) {
self.sides = sides
self.generator = generator
}
func roll() -> Int {
return Int(generator.random() * Double(sides)) + 1
}
}
let sixRoll = Dice(sides:6, generator:
LinearCongruentialGenerator())
for _ in 1...15 {
println("Random dice roll is \(sixRoll.roll())")
}
Here's a random number: 0.0976580361225423
Random dice roll is 1
Random dice roll is 5
Random dice roll is 6
Random dice roll is 4
Random dice roll is 2
Random dice roll is 6
Random dice roll is 6
Random dice roll is 6
Random dice roll is 6
Random dice roll is 1
Random dice roll is 1
Random dice roll is 4
Random dice roll is 1
Random dice roll is 2
Random dice roll is 5
RandomNumberGeneratorというプロトコールを作って、これをタイプ(型:type)として使うため、というか、プロトコールはこういう風に型として使うことを目的として考えられているんでしょう。前日のようにクラスのメソッドで宣言して実装するだけなら必要のない機能になるけど、今日の例文のように、拡張して行く場合にその存在理由がはっきりしてくる。あくまでもprotocolは概念のみで何も実装されていないが、そういう概念ということは型と同様ということですよね。IntやStringのようなもんですよね。したがって、クラスDiceのプロパティの型宣言に使われているということになる。しかし、概念のみではインスタンスを生成する時に何も起こらないので、インスタンスを生成するときは、概念が形となったクラスLinearCongruentialGeneratorを引数としてDice型インスタンス生成に使用しなければんらないということだろう。自分で書いていながら混乱しているが、なんとなくプロトコールの拡張性が見えたような気がする。