プロトコル準拠をチェックし、特定のプロトコルにキャストするために、Type Casting で説明されている is と as の演算子を使用することができます。プロトコルのチェックとキャストは、型のチェックとキャストとまったく同じシンタックスになります。

  • is 演算子は、インスタンスがプロトコルに準拠する場合に true を返し、そうでない場合は false を返す。
  • as? ダウンキャスト演算子は、プロトコルの型のオプショナル値を返し、インスタンスがそのプロトコルに準拠しない場合にはこの値は nil になります。
  • as! ダウンキャスト演算子は、プロトコル型へのダウンキャストを強制し、ダウンキャストが成功しない場合には実行時エラーを引き起こします。

次の例では、gettable な Double プロパティ area をプロパティ要件とするプロトコル HasArea を定義しています。

protocol HasArea {
    var area: Double { get }
}

次は、共に HasArea プロトコルに準拠する Circle クラスと Country クラスです。

class Circle: HasArea {
    let pi = 3.1415927
    var radius: Double
    var area: Double { return pi * radius * radius }
    init(radius: Double) { self.radius = radius }
}
class Country: HasArea {
    var area: Double
    init(area: Double) { self.area = area }
}

Circle クラスは、ストアドプロパティの radius をベースに、コンピューテッドプロパティとして area プロパティ要件を実装しています。Country クラスは、ストアドプロパティとして直接的に area 要件を実装しています。どちらのクラスも適切に HasArea プロトコルに準拠しています。

次は Animal クラスで、HasArea プロトコルに準拠していません。

class Animal {
    var legs: Int
    init(legs: Int) { self.legs = legs }
}

CircleCountry および Animal クラスには、共有のベースクラスはありません。それでも、それらはすべてクラスであり、AnyObject 型の値を保管する配列を初期化するために、それぞれの型のインスタンスを使用することができます。

let objects: [AnyObject] = [
    Circle(radius: 2.0),
    Country(area: 243_610),
    Animal(legs: 4)
]

radius が 2 の Circle インスタンス、英国の表面積の平方キロメートルで初期化された Country インスタンス、そして 4 本の足を持つ Animal インスタンスを含む配列リテラルで、objects 配列は初期化されています。

objects 配列内を繰り返し処理することができ、配列内の各オブジェクトが HasArea プロトコルに準拠しているかをチェックすることができます。

for object in objects {
    if let objectWithArea = object as? HasArea {
        print("Area is \(objectWithArea.area)")
    } else {
        print("Something that doesn't have an area")
    }
}
// Area is 12.5663708
// Area is 243610.0
// Something that doesn't have an area

配列内のオブジェクトが HasArea プロトコルに準拠している場合、as? 演算子で返されるオプショナル値が、オプショナルバインディングで定数 objectWithArea にアンラップされます。定数 objectWithArea が HasArea 型であるとわかっているため、型安全にその area プロパティにアクセスして出力することができます。

オブジェクトがキャスト処理によって変更されているわけではないことに注目してください。引き続き、それらは CircleCountry および Animal です。しかしながら、定数 objectWithArea に保管されている時には HasArea 型であるとだけわかっているため、area プロパティにのみアクセスすることができます。


Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.