안녕하세요! 오늘은 Extension에 대한 포스팅을 작성하려고 합니다.
바로 공식 문서 정의를 확인해볼까요?

Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you don’t have access to the original source code (known as retroactive modeling).
확장은 기존에 존재하는 클래스, 구조체, 열거형, 프로토콜 타입에 새로운 기능을 추가하는 것이다. 기존 orginal 소스 코드에 접근하지 않아도 기능을 확장하는 것이 가능하다.
네! 이렇게 확장은 기존 구현되어 있는 클래스, 구조체 등에 새로운 기능을 추가하는 것입니다.
확장은 'extension' 키워드를 입력하여 사용할 수 있습니다.
class SomeType{ // 기존 타입
}
extension SomeType { // 확장
// new functionality to add to SomeType goes here
}
확장이 정의되기 전에 인스턴스가 생성된 경우에도 확장을 통해 정의된 새 기능 사용 가능합니다.
상속이 수직 확장이라면 수평은 수평 확장이라고 할 수 있습니다.
현재 존재하는 타입에 새로운 기능을 추가하는 것이므로 저장 속성을 추가할 수 없습니다.
스위프트에서는 확장으로 구현된 메서드에 대해서 상속을 통한 제정의가 불가능합니다. (@objc 붙이면 가능)
extension Int {
var squared: Int {
return self * self
}
}
5.squared // 25
4.squared // 16
확장에서는 메서드 형태만 정의할 수 있습니다. (저장 속성은 확장 기능에서 정의 불가능) 좀 더 자세히 살펴보자면 아래와 같이 총 6가지가 확장으로 정의가 가능합니다.
(타입) 계산 속성 또는 (인스턴스) 계산 속성이 확장 가능합니다.
❌❌ 저장 속성은 안되고 기존 속성의 속성관찰자는 추가할 수 없습니다. ❌❌
extension Double {
static var zero: Double { return 0.0 }
}
Double.zero
기존 Int 타입에 printNumbersFrom1to5 이름의 메서드를 추가한 예시입니다.
Int.random(in: 1...100)
extension Int {
static func printNumbersFrom1to5() {
for i in 1...5 {
print(i)
}
}
}
Int.printNumbersFrom1to5()
클래스, 구조체에 새로운 생성자를 정의할 수 있습니다. 하지만 클래스, 구조체에 따라 생성할 수 있는 생성자에 차이가 있습니다.
// UIColor 기본 생성자
var color = UIColor(red: 0.3, green: 0.5, blue: 0.4, alpha: 1)
extension UIColor { // 편의생성자
convenience init(color: CGFloat) { // Float / Double
self.init(red: color/255, green: color/255, blue: color/255, alpha: 1)
}
}
struct Point{
var x: Int = 0
var y: Int = 0
}
extension Point{
init(num: Double){
self.x = num
self.y = num
}
}
서브 스크립트 또한 확장이 가능합니다.
예를 들어, Int 타입에 서브스크립트를 사용하여 자릿수를 리턴하는 메서드를 구현할 수 있습니다.
extension Int {
subscript(num: Int) -> Int {
var decimalBase = 1
for _ in 0..<num {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
123456789[0]
클래스, 구조체 및 열거형에 새 중첩 유형을 추가할 수 있습니다.
예를 들어, Int 타입에 중첩 열거형을 추가해보겠습니다.
extension Int {
enum Kind { // 음수, 0, 양수
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return Kind.zero
case let x where x > 0:
return Kind.positive
default:
return Kind.negative
}
}
}