こんにちワッフル #挨拶
こんにちワッフル
— しゅうまい君 (@shuumai) 2014, 8月 9
さっそくですがだめサンプル
突然ですが、以下のコードをご覧ください。これ何故か動かないんですよ。
public protocol Shape { func draw() } public class Triangle : Shape { public func draw() { println("三角形!") } } public class Rectangle : Shape { public func draw() { println("長方形!") } } // インスタンス化します let triangle : Shape = Triangle() let rectangle : Shape = Rectangle() // Shape型の配列に入れます let shapes : [Shape] = [triangle, rectangle] // shapesの要素に、triangleが含まれているか // 以下のコードはコンパイルエラーになります for shape : Shape in shapes { if triangle === shape { shape.draw() } }
コンパイルすると、以下のエラーが出てしまいます。
Type 'Shape' does not conform to protocol 'AnyObject'
どうやら Swift の場合、コンパイル時に内部的な型チェックが走っていて(なんでやねん)、しかもそれが上記のコードではうまく働いていないようです*1。
困り果てて“The Swift Programming Language”, Apple Inc., Aug 4, 2014. 版*2 を読み直していたら、こんな記載を 今さら 発見。
@objc protocol HasArea { var area: Double { get } }You can check for protocol conformance only if your protocol is marked with the @objc attribute, as seen for the HasArea protocol above. This attribute indicates that the protocol should be exposed to Objective-C code and is described in Using Swift with Cocoa and Objective-C. Even if you are not interoperating with Objective-C, you need to mark your protocols with the @objc attribute if you want to be able to check for protocol conformance.
型チェックしたいプロトコルは、宣言時に @objc 属性を明示してくださいね、べつに Objective-C コードを混ぜ書きしたいわけでない場合でも、この属性は必要なんだよ、という意味だと思います。よくわからないですが。
というわけで、上記の Shape プロトコルを以下のように修正したら、無事コンパイルが通るようになりました。
@objc public protocol Shape { func draw() }
めでたし、めでたし。