Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
extension + protocol / デフォルト実装
extensionとprotocolを組み合わせることで、既存の型にprotocol準拠を後から追加(retroactive conformance)したり、protocolにデフォルト実装を提供したりできます。
構文
// 既存の型にprotocol準拠を追加
extension 既存の型名: プロトコル名 {
// 必須メソッドの実装
}
// protocolにデフォルト実装を追加
extension プロトコル名 {
func メソッド名() { /* デフォルト実装 */ }
}
構文一覧
| 構文 | 概要 |
|---|---|
| extension 型: Protocol { } | 既存の型にプロトコル準拠を後付けします(retroactive conformance)。 |
| extension Protocol { func f() {} } | プロトコルにデフォルト実装を追加します。準拠する型で実装を省略できます。 |
| extension Protocol where Self: 型 { } | 特定の型にのみ適用される条件付き実装を追加します。 |
サンプルコード
protocol Describable {
func describe() -> String
}
// デフォルト実装
extension Describable {
func describe() -> String {
return "これは \(type(of: self)) です"
}
}
// IntをDescribableに準拠させる(retroactive conformance)
extension Int: Describable {
func describe() -> String {
return "整数値: \(self)"
}
}
// Stringはデフォルト実装を使う
extension String: Describable { }
print(42.describe())
print("Hello".describe())
// where句で条件付き拡張
protocol Summable {
static func +(lhs: Self, rhs: Self) -> Self
static var zero: Self { get }
}
extension Array where Element: Summable {
func sum() -> Element {
return reduce(Element.zero, +)
}
}
extension Int: Summable { static var zero: Int { 0 } }
print([1, 2, 3, 4, 5].sum())
概要
extensionとprotocolの組み合わせはSwiftで最も重要なパターンのひとつです。標準ライブラリ自体もこの仕組みで構築されています(『Comparable』を準拠すると『<=』『>=』が自動で使えるなど)。
外部モジュール(他のライブラリ)の型を外部のprotocolに準拠させるretroactive conformanceは、Swift 5.7以降でコンパイラ警告が出るようになりました。自分が定義した型か、自分が定義したprotocolのどちらかを使う場合は問題ありません。
extensionの基本はextensionの基本を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。