기본 문법 공부(확장(expansion) - 익스텐션(Extensions), 익스텐션 문법)
이 포스트는 야곰님의 Swift 프로그래밍 2판을 보고 스스로 공부한 내용을 정리한 포스트 입니다.
참고 자료
익스텐션(Extension)이란
-
익스텐션(Extension)은
스위프트의 강력한 기능 중 하나로구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있다.
-
기능을 추가하려는 타입을 구현한 소스 코드를 알지 못하거나 볼 수 없다 해도, 타입만 안다면 그 타입의 기능을 확장할 수도 있다.
-
익스텐션은 Objective-C의 카테고리와 유사한 기능이다.
-
Objective-C의 카테고리는 카테고리마다 이름을 명명했지만
스위프트의 익스텐션은 이름이 없다.
-
스위프트의 익스텐션이 타입에 추가할 수 있는 기능은 다음과 같다
-
1) 연산 타입 프로퍼티(Computed Type Property) / 연산 인스턴스 프로퍼티(Instance Type Property)
-
2) 타입 메서드(Type Method) / 인스턴스 메서드(Instance Method)
-
3) 이니셜라이저(Initializer)
-
4) 서브스크립트(Subscript)
-
5) 중첩 타입
-
6) 특정 프로토콜을 준수할 수 있도록 기능 추가
-
-
익스텐션은 타입에 새로운 기능을 추가할 수는 있지만, 기존에 존재하는 기능을 재정의(override)할 수 없다.
-
클래스의 상속과 익스텐션은 비슷해보이지만 실제 성격은 많이 다르다.
-
클래스의 상속은 클래스 타입에서만 가능
하지만익스텐션은 구조체, 클래스, 프로토콜 등에 적용이 가능하다.
-
또,
클래스의 상속
은특정 타입을 물려받아 하나의 새로운 타입을 정의하고 추가 기능을 구현하는 수직 확장
이지만,익스텐션
은기존의 타입에 기능을 추가하는 수평확장이다.
-
상속(Inheritance)을 받으면 기존 가능을 재정의(override)할 수 있지만
,익스텐션은 재정의할 수 없다
는 것도큰 차이 중 하나이다.
-
상황와 용도에 맞게 상속과 익스텐션을 선택하여 사용하면 된다.
-
-
익스텐션을 사용하는 대신 원래 타입을 정의한 소스에 기능을 추가하는 방법도 있겠지만
,외부 라이브러리나 프레임워크를 가져다 사용했다면 원본 소스를 수정하지 못한다.
-
외부에서 가져온 타입에 내가 원하는 기능을 추가하고자 할 때 익스텐션(extension)을 사용한다.
- 따로 상속을 받지 않아도 되며, 구조체와 열거형(구조체와 열거형은 상속 불가)에도 기능을 추가할 수 있으므로 익스텐션은 매우 편리하다.
-
-
익스텐션은 모든 타입에 적용할 수 있다.
-
모든 타입이라 함은 구조체, 열거형, 클래스, 프로토콜, 제네릭 타입 등을 뜻한다.
-
즉, 익스텐션을 통해 모든 타입에 연산 프로퍼티, 메서드, 이니셜라이저, 서브스크립트, 중첩 데이터 타입 등을 추가할 수 있다.
-
익스텐션 문법
익스텐션은 extension이라는 키워드를 사용하여 선언한다.
extension 확장할 타입 이름 {
// 타입에 추가될 새로운 기능 구현
}
익스텐션은 기존에 존재하는 타입이 추가로 다른 프로토콜을 채택할 수 있도록 확장할 수도 있다.
extension 확장할 타입 이름: 프로토콜 1, 프로토콜 2, 프로토콜 3 {
// 프로토콜 요구사항 구현
}
-
스위프트 라이브러리를 살펴보면 실제로 익스텐션이 굉장히 많이 사용됨을 알 수 있다.
-
Double 타입에는 수많은 프로퍼티와 메서드, 이니셜라이저가 정의되어 있으며 수많은 프로토콜을 채택할 것으로 예상되지만, 실제로 Double 타입의 정의를 살펴보면 그 모든 것이 다 정의되어 있지는 않다.
// 스위프트 표준 라이브러리의 Double 타입 정의
/// A double-precision, floating-point value type.
public struct Double {
public init()
public init(_ v: UInt8)
public init(_ v: Int8)
public init(_ v: UInt16)
// 중략...
}
Double 타입에서 채택하고 준수해야 하는 수많은 프로토콜은 익스텐션을 통해 채택하고 준수하도록 정의되어 있다.
// 스위프트 표준 라이브러리의 Double 타입에 구현한 익스텐션의 일부 코드
extension Double: CustomStringConvertible {
/// A textual representation for the value.
public var description: String { get }
}
extension Double: CustomReflectable {
/// A mirror that reflects the 'Double' instance.
public var customMirror: Mirror { get }
}
// 중략...
-
이처럼 스위프트 표준 라이브러리 타입의 기능은 대부분 익스텐션으로 구현되어 있다.
-
Double 외에도 다른 타입들의 정의와 익스텐션을 찾아보면 더 많은 예를 볼 수 있다.