見出し画像

楽しい!Swift。 - A Swift Tour Protocols and Extensions

プロトコルを宣言するために protocol を使います。

protocol ExampleProtocol {
     var simpleDescription: String { get }
     mutating func adjust()
}

protocolに準拠させてクラス、構造体を作って使うことができます。

クラス

class SimpleClass: ExampleProtocol {
     var simpleDescription: String = "A very simple class."
     var anotherProperty: Int = 69105
     
   func adjust() {
          simpleDescription += "  Now 100% adjusted."
     }
}

使います。

var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription


構造体

struct SimpleStructure: ExampleProtocol {
     var simpleDescription: String = "A simple structure"
     
   mutating func adjust() {
          simpleDescription += " (adjusted)"
     }
}

使います。

var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription


mutating func adjust()

構造体 SimpleStructure は変更があるメソッドについては mutating つける必要があります。クラスSimpleClassのメソッドはもともと変更することができるので、mutating を付ける必要はありません。

既存の型に新しい機能(メソッドや計算プロパティ)を追加する場合にextension を使います。他のファイルやモジュールで宣言された型や、ライブラリやフレームワークからインポートした型にプロトコルを準拠させる場合にも extension を使います。

extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
 }
print(7.simpleDescription)
// Prints "The number 7"

プロトコルの名前は、型名と同じ感覚で使えます。例えば、同じ 1 つのプロトコルに準拠した別の型のオブジェクトを作成することができます。

Box プロトコル型の値をそのまま扱っている場合、プロトコル以外で定義されたメソッドを使用することはできません。

let protocolValue: any ExampleProtocol = a
print(protocolValue.simpleDescription)
// Prints "A very simple class.  Now 100% adjusted."

変数 protocolValue が実行時に SimpleClass になりますが、コンパイラはこれを、ExampleProtocol として認識しています。

ExampleProtocolが定義しているのは

var simpleDescription: String { get }
mutating func adjust()

なので

print(protocolValue.anotherProperty)  

を実行しても、"anotherProperty"はSimpleClassのプロパティなので、この場合は認識されずエラーとなります。

この記事が気に入ったらサポートをしてみませんか?