SwiftのExtension: 概要、構文、およびメソッドの追加方法

著者: IT Sectr 公開日: 2026-06-18 読了時間: 6 分

ExtensionはSwiftにおけるメカニズムで、既存の型のソースコードを変更せずに新しい機能を追加できます。拡張はメソッド、計算プロパティ、イニシャライザ、サブスクリプト、ネスト型、プロトコル準拠をサポートします。Apple Documentation, 2026によると、extensionsはSwiftプロジェクトにおけるコード整理とオープン/クローズド原則の遵守のための重要なツールです。

重要なポイント

  • Extension — 元の型を変更せずに既存の型に機能を追加
  • 計算プロパティ — extensionで追加可能、格納プロパティは不可
  • プロトコル準拠 — extensionによる任意の型へのプロトコル実装
  • コード整理 — extensionsは関連するロジックをプロトコルごとにグループ化
  • オープン/クローズド — extensionsは拡張に対する開放の原則を実装

SwiftのExtensionとは?

ExtensionはSwiftの言語構造で、既存の型(クラス、構造体、enum、プロトコル)を新しい機能で拡張できます。Objective-Cのカテゴリに似ていますが、より強力です。

Extensionで追加できるもの:

  • 計算プロパティ — インスタンスと型
  • メソッド — インスタンスと型
  • イニシャライザ(convenience init)
  • サブスクリプト
  • ネスト型
  • プロトコル準拠

Appleのドキュメントによると、extensionは既存のメソッドをオーバーライドできず(動的ディスパッチ)、格納プロパティも追加できません。これらの制限は元の型の整合性を保ちます。

拡張の構文

Extensionはキーワードextensionの後に拡張する型を指定して宣言します。

swift
extension Double {
    var km: Double { return self * 1000.0 }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1000.0 }
}

let distance = 5.0.km
print("5 km = \(distance) meters") // 5000.0

独自の型だけでなく、Swift、Foundation、UIKit、その他のフレームワークの標準ライブラリの型も拡張できます。これにより、extensionはドメイン固有の機能を追加するための強力なツールになります。

Extensionによるメソッドの追加

Extensionは既存の任意の型にインスタンスメソッドと型メソッドを追加できます。

swift
extension String {
    func isValidEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
        return self.range(of: emailRegex, options: .regularExpression) != nil
    }

    static func random(length: Int) -> String {
        let letters = "abcdefghijklmnopqrstuvwxyz0123456789"
        return String((0..<length).map { _ in letters.randomElement()! })
    }
}

let email = "user@example.com"
print(email.isValidEmail()) // true
let code = String.random(length: 8) // "a3f8k2m1"

Mutatingメソッドは値型(struct、enum)を拡張し、selfを変更できます。クラスにはmutatingは不要です。Extensionは標準ライブラリの型にもmutatingメソッドを追加できます。

Extensionでの計算プロパティ

Extensionは計算プロパティのみ追加可能で、格納プロパティは許可されません。extensionが元の型のメモリを管理しないため、これは理にかなっています。

swift
extension Date {
    var isPast: Bool {
        return self < Date()
    }

    var isToday: Bool {
        return Calendar.current.isDateInToday(self)
    }
}

let someDate = Date().addingTimeInterval(3600)
print(someDate.isPast) // false (one hour from now is future)

Extensionでの計算プロパティはメインの実装と同じルールに従います。{ get }および{ get set }プロパティを作成できます。Swiftは1つの型に対する拡張の数に制限を設けていません。異なるファイルに1つの型に対する拡張をいくつでも宣言できます。これは大規模プロジェクトでは標準的なプラクティスです。

Extensionによるプロトコル準拠

Extensionはプロトコルを実装する推奨方法です。メインの型宣言を乱雑にする代わりに、すべてのプロトコルメソッドを別のextensionに配置します。

swift
struct User {
    let id: Int
    let name: String
    let email: String
}

// Extension per protocol — clean separation
extension User: Equatable {
    static func == (lhs: User, rhs: User) -> Bool {
        return lhs.id == rhs.id
    }
}

extension User: Codable {
    enum CodingKeys: String, CodingKey {
        case id, name, email
    }
}

このアプローチは責任を分離します。メインの構造体には格納プロパティのみを含め、extensionsにプロトコル実装を含めます。Swiftは制御外の型に対してもextensionによるプロトコル実装を許可します。

Extensionとコード整理

Extensionは単なる言語機能ではなく、アーキテクチャ整理のためのツールです。拡張を適切に使用することで、コードは読みやすく保守しやすくなります。

  • プロトコルごとのグループ化 — 各プロトコルを別のextensionに
  • マーク(MARK)// MARK: - Equatableでナビゲーション
  • ファイル分離 — 異なるプロトコルの拡張を異なるファイルに
  • プライベートヘルパー — extension内のプライベートメソッドはprivateとマーク
swift
// MARK: - User + Displayable
extension User: Displayable {
    var displayName: String {
        return "\(name) (\(email))"
    }
}

Swift API Design Guidelinesによると、extensionsは可読性を向上させます。開発者はメイン宣言でデータ構造を、extensionsでロジックを見ることができます。これはインターフェース分離の原則に沿っています。

where制約付きのextensionは特定の型にのみメソッドを追加します:extension Array where Element: Equatable { func isUnique() -> Bool }。このようなコードは簡潔で型安全です。isUniqueメソッドはEquatable要素を持つ配列にのみ現れ、コンパイル時のエラーを排除し、APIをよりクリーンで安全、そして他の開発者にとって明確にします。

よくある質問

Extensionは格納プロパティを追加できますか?

いいえ、extensionは格納プロパティを追加できません。この制限は基本的なものです。extensionは型インスタンスのメモリ割り当てに関与しません。格納プロパティにはメインの型宣言を使用してください。

Extensionで既存のメソッドをオーバーライドできますか?

いいえ、extensionはメソッドをオーバーライドできません。既存のメソッドと同じシグネチャでメソッドを宣言しようとすると、コンパイルエラーになります。オーバーライドにはクラスの継承を使用してください。

Extensionとサブクラス化の違いは?

Extensionは新しい型を作成せずに機能を追加します。サブクラス化は階層を作成し、オーバーライドをサポートします。Extensionは元のソースコードへのアクセスを必要とせず、すべての型で機能します。

Extensionはジェネリックにできますか?

はい、拡張する型がジェネリックであれば、extensionもジェネリックにできます:extension Array where Element: Numeric。また、extension内に独自の型パラメータを持つジェネリックメソッドを追加することもできます。

Extensionはパフォーマンスに影響しますか?

Extensionはパフォーマンスに影響しません。extensionのメソッドは通常のメソッドとしてコンパイルされます。extension付きプロトコルには静的ディスパッチが使用され、クラスの動的ディスパッチよりも高速になる場合があります。

まとめ

  • Extensionは計算プロパティ、メソッド、プロトコル、サブスクリプトを追加
  • 格納プロパティは不可 — extensionはメモリを割り当てない
  • プロトコル準拠をextensionで行うのがSwiftの標準的なコード整理方法
  • オープン/クローズドの原則 — 型は拡張に開かれ、修正に閉じている
  • ジェネリック拡張とwhere句で特殊化された振る舞いを提供
  • 可読性 — extensionsはプロトコルと機能ごとにロジックをグループ化

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください