[Swift]protocol、再び

Object Orientedではなく、Protocol Oriented(Swift)への理解を深めたい最近です。

https://www.raywenderlich.com/109156/introducing-protocol-oriented-programming-in-swift-2

の記事をざっと読みながら思ったのですが、protocolでは let の定義がつかえないことに疑問を覚えました。StackOverflowでも確かにありました。

http://stackoverflow.com/questions/34385897/why-i-cant-use-let-in-protocol-in-swift

protocolは抽象インタフェースになるので、具体的な値が入りません。letはconstantな振る舞いが必要ですが、protocol自体は具体的な値はその具体化されたstructやclass、enumなどで変化するためですね。なので、protocolでは var を使う必要があります。ただ、そのstructなどのprotocolを引き継ぐ時はその先で let を使ったりできます。

なるほどね。

ちなみに、以下がprotocolとそれを使ってstructやenum、extensionした簡単な例です。protocolで { set } を指定していると、当然ながらemutableではいられないので継承した先で同名の変数は let で定義することはできません。


protocol MyProtocol {
var name: String { get }
var myBool: Bool { get set }
func hello() -> String
}
protocol MyProtocol2: BooleanType {
var name: String { get }
var myBool: Bool { get }
}
struct MyStruct: MyProtocol {
let name = "hi"
var myBool = true
func hello() -> String {
return "world!"
}
}
// Can'tuse MyProtocol because `var myBool: Bool` in this case is imulable.(So, it doesn't allowed to "set".)
enum MyEnum: MyProtocol2 {
case A
case B
var name: String {
switch self {
case .A:
return "A"
case .B:
return "B"
}
}
var myBool: Bool {
switch self {
case .A:
return true
case .B:
return false
}
}
}
// Extend BooleanTyle for MyProtocol2
extension BooleanType where Self: MyProtocol2 {
var boolValue: Bool {
return self.myBool
}
}
MyEnum.A.myBool
MyEnum.A.boolValue // Defined via extension BooleanType

extensionの書き方、 when Self: XXXX という感じて拡張する先を書くのですね。Elixirだとdefimplで for XXX みたいな感じで書いているところ。なるほど。

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.