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 みたいな感じで書いているところ。なるほど。