ExtensionはSwiftにおけるメカニズムで、既存の型のソースコードを変更せずに新しい機能を追加できます。拡張はメソッド、計算プロパティ、イニシャライザ、サブスクリプト、ネスト型、プロトコル準拠をサポートします。Apple Documentation, 2026によると、extensionsはSwiftプロジェクトにおけるコード整理とオープン/クローズド原則の遵守のための重要なツールです。
重要なポイント
ExtensionはSwiftの言語構造で、既存の型(クラス、構造体、enum、プロトコル)を新しい機能で拡張できます。Objective-Cのカテゴリに似ていますが、より強力です。
Extensionで追加できるもの:
Appleのドキュメントによると、extensionは既存のメソッドをオーバーライドできず(動的ディスパッチ)、格納プロパティも追加できません。これらの制限は元の型の整合性を保ちます。
Extensionはキーワードextensionの後に拡張する型を指定して宣言します。
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 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 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に配置します。
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は単なる言語機能ではなく、アーキテクチャ整理のためのツールです。拡張を適切に使用することで、コードは読みやすく保守しやすくなります。
// MARK: - Equatableでナビゲーションprivateとマーク// 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 Array where Element: Numeric。また、extension内に独自の型パラメータを持つジェネリックメソッドを追加することもできます。
Extensionはパフォーマンスに影響しません。extensionのメソッドは通常のメソッドとしてコンパイルされます。extension付きプロトコルには静的ディスパッチが使用され、クラスの動的ディスパッチよりも高速になる場合があります。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。