Extension은 Swift에서 기존 타입의 소스 코드를 변경하지 않고 새로운 기능을 추가할 수 있는 메커니즘입니다. 확장은 메서드, 계산 특성, 초기화자, subscripts, 중첩 타입 및 프로토콜 줄수를 지원합니다. Apple Documentation, 2026에 따르면, extensions은 Swift 프로젝트에서 코드 조직과 Open/Closed Principle을 준수하는 데 중요한 도구입니다.
주요 포인트
Extension은 Swift의 언어 구조로, 기존 타입(클래스, 구조체, enum, 프로토콜)을 새로운 기능으로 확장할 수 있습니다. Objective-C의 카테고리와 유사하지만 더 강력합니다.
Extension이 추가할 수 있는 것:
Apple 문서에 따르면, extension은 기존 메서드를 재정의(dynamic dispatch)하거나 저장 특성을 추가할 수 없습니다. 이러한 제한은 원본 타입의 완전성을 보존합니다.
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는 하나의 타입에 대한 extension 수에 제한을 두지 않습니다. 서로 다른 파일에서 하나의 타입에 대해 원하는 만큼의 extension을 선언할 수 있습니다. 이는 대형 프로젝트에서 표준 실무입니다.
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은 단순한 언어 기능이 아닌 아키텍처 조직의 도구입니다. 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은 새 타입을 만들지 않고 기능을 추가합니다. Subclassing은 계층 구조를 만들고 재정의를 지원합니다. Extension은 원본 소스 코드에 액세스할 필요가 없고 모든 타입과 작동합니다.
네, extension은 확장된 타입이 제네릭인 경우 제네릭일 수 있습니다: extension Array where Element: Numeric. extension 내에 자체 타입 매개변수가 있는 제네릭 메서드도 추가할 수 있습니다.
Extension은 성능에 영향을 미치지 않습니다. extension 메서드는 일반 메서드처럼 컴파일됩니다. extension이 있는 프로토콜에는 정적 디스패치가 사용되어 클래스의 동적 디스패치보다 빠른 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.