확장 (Extensions) 확장한 클래스, 구조체, 열거형, 또는 프로토콜 타입에 새로운 기능을 추가합니다. 이것은 기존 소스 코드에 접근 권한이 없는 타입을 확장하는 기능이 포함됩니다
- 계산된 인스턴스 프로퍼티와 계산된 타입 프로퍼티 추가
- 인스턴스 메서드와 타입 메서드 정의
- 새로운 초기화 구문 제공
- 서브 스크립트 정의
- 새로운 중첩된 타입 정의와 사용
- 기존 타입이 프로토콜을 준수하도록 함
주의
확장은 타입에 새로운 기능을 추가할 수 있지만 기존 기능을 재정의 할 수는 없습니다.
extension SomeType {
// new functionality to add to SomeType goes here
}
확장은 하나 이상의 프로토콜을 채택하여 기존 타입을 확장할 수 있습니다. 프로토콜 준수를 추가하려면 클래스 또는 구조체에 대해 작성하는 것과 동일하게 프로토콜 이름을 작성합니다
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}
확장은 기존 인스턴스 생성 순서에 상관없이 사용 가능
저장 프로퍼티는 추가할 수 없고, 연산 프로퍼티만 추가 가능
extension Int {
var half: Int {
return self / 2
}
}
위의 연산 프로퍼티는 이제 모든 타입에서 사용 가능
let num = 100
print(num.half) // 50
인스턴스, 타입 메서드 모두 추가 가능
// 타입 메서드
extension Int {
static func printZero() {
print(0)
}
}
Int.printZero() // 0
// 인스턴스 메서드
extension Int {
func printDouble() {
print(self * 2)
}
}
let num = 100
num.printDouble() //200
Designated initializer는 추가할 수 없고 Convenience initializer만 추가할 수있으며,
deinitializer를 추가할 수 없다
- Designated는 우리가 지금까지 써왔던 deinit, init
- Convenience는 부분적인 init? 같은 건데 아직은 잘 모르겠음. 다만 convenience는 최종적으로 Designated를 호출해야함
extension으로 생성자를 추가할 경우, Memberwise Initializer를 보존하며 새로운 생성자를 추가할 수 있다
위와 같은 init이 Memberwise 임
근데 struct에서는 직접 init을 구현하면 memberwise를 더이상 제공하지 않음
struct PointStruct {
let x: Int
let y: Int
init(value: Int) {
self.x = value
self.y = value
}
}
하지만 extension을 사용해서 init을 구현하면 memberwise를 보존할 수 있음
struct PointStruct {
let x: Int
let y: Int
}
extension PointStruct {
init(value: Int) {
self.x = value
self.y = value
}
}