この世でいちばんわかりやすいiPhoneアプリ開発のおはなし【プロトコル】
プログラムの中で、そのコードが「どのような使われ方をするか」を決める規約を プロトコル といいます。 実際にプロトコルを使って、その利便性を理解しましょう。
ここでは、フルーツをモデル化する構造体を考えます。
struct Fruit {
var name: String
var emoji: String
}
上のコードは、フルーツの「名前」に加えて、美味しそうな「絵文字」を示すプロパティを定義しています。
さっそく、フルーツのインスタンスをいくつか作成しましょう。
let orange = Fruit(name: "Orange", emoji: "🍊")
let banana = Fruit(name: "Banana", emoji: "🍌")
メンバーワイズ・イニシャライザに適切な名前と絵文字を指定して、インスタンスを作成できました。 これらのFruit型インスタンスをコンソールに出力してみましょう。
print(orange) // Fruit(name: "Orange", emoji: "🍊")
print(banana) // Fruit(name: "Banana", emoji: "🍌")
予想とは少し違う、何か仰々しい内容が表示されました。 これは、Fruit型が「どのようにコンソール出力するか」という規約に適合していないことが原因です。
型のインスタンスを「どのようにコンソール出力するか」は、CustomStringConvertibleプロトコルが定めます。 型がこのプロトコルを 採用 することで、「どのようにコンソール出力するか」を決められるようになります。
プロトコルを採用するには、型名の宣言の後にコロン記号:をつけてプロトコル名を記述します。
struct Fruit: CustomStringConvertible {
var name: String
var emoji: String
}
型にCustomStringConvertibleプロトコルを採用すると、コンパイラはエラーを報告します。 これは、プロトコルが「採用した型」に対して要求する条件を、Fruitが満たしていないことが原因です。
CustomStringConvertibleプロトコルの要件とは、「descriptionという名前の計算プロパティが文字列を返す」ことです。
struct Fruit: CustomStringConvertible {
var name: String
var emoji: String
var description: String {
return ""
}
}
要件を満たす計算プロパティを実装すると、エラーは解消されます。
このdescriptionプロパティの返り値が、コンソールに出力される内容です。 名前と絵文字かシンプルに表示されるようにしましょう。
struct Fruit: CustomStringConvertible {
var name: String
var emoji: String
var description: String {
return "\(self.name) \(self.emoji)"
}
}
これで、Fruit型はCustomStringConvertibleプロトコルに適合しました。 したがって、コンソールには「意図した通りの内容」が出力されるようになります。
print(orange) // Orange 🍊
print(banana) // Banana 🍌
Swiftには、他にも様々なプロトコルが提供されています。 独自のプロトコルを定義することも可能です。 プロトコルと構造体を駆使することによって、Swiftはシンプルかつ柔軟性に富んだプログラミングを実現しています。