[Swift] Extension (확장)

어흥·2024년 5월 21일

Swift

목록 보기
14/28

안녕하세요! 오늘은 Extension에 대한 포스팅을 작성하려고 합니다.

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 붙이면 가능)

장점

  1. 원본 소스 코드에 대한 액세스 권한이 없는 유형에 대해서 기능을 추가하고 싶을 때 사용하면 매우 유용합니다. 원본 소스 코드를 변경하지 않고도 원하는 기능을 추가하여 사용할 수 있기 때문입니다.
  • 예: Int, String, Double과 같이 애플이 미리 만들어 놓은 타입
extension Int {
    var squared: Int {
        return self * self
    }
}
5.squared // 25
4.squared // 16
  1. 코드의 가독성을 크게 향상시킬 수 있습니다.
    많은 기능을 담고 있는 클래스인 경우, extension을 사용하여 요구사항에 따라 기능을 분리하면 가독성을 높일 수 있습니다.
  • 예: viewcontroller 클래스

확장 가능 멤버의 종류

확장에서는 메서드 형태만 정의할 수 있습니다. (저장 속성은 확장 기능에서 정의 불가능) 좀 더 자세히 살펴보자면 아래와 같이 총 6가지가 확장으로 정의가 가능합니다.

  1. (인스턴스) 계산 속성, 타입 계산 속성
  2. (인스턴스) 메서드, 타입 메서드
  3. 새로운 생성자
  4. subscript(서브 스크립트)
  5. 새로운 중첩 타입 정의 및 사용
  6. 프로토콜 채택 및 프로토콜 관련 메서드

1. 계산 속성

(타입) 계산 속성 또는 (인스턴스) 계산 속성이 확장 가능합니다.
❌❌ 저장 속성은 안되고 기존 속성의 속성관찰자는 추가할 수 없습니다. ❌❌

extension Double {
    static var zero: Double { return 0.0 }
}

Double.zero

2. 메서드

기존 Int 타입에 printNumbersFrom1to5 이름의 메서드를 추가한 예시입니다.

  • 1부터 5까지 출력하는 함수
Int.random(in: 1...100)

extension Int {
    static func printNumbersFrom1to5() {
        for i in 1...5 {
            print(i)
        }
    }
}
Int.printNumbersFrom1to5()

3. 새로운 생성자

클래스, 구조체에 새로운 생성자를 정의할 수 있습니다. 하지만 클래스, 구조체에 따라 생성할 수 있는 생성자에 차이가 있습니다.

  • 클래스: 편의 생성자만 생성 가능
// 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
    } 
}

4. 서브스크립트(subscript)

서브 스크립트 또한 확장이 가능합니다.
예를 들어, Int 타입에 서브스크립트를 사용하여 자릿수를 리턴하는 메서드를 구현할 수 있습니다.

extension Int {
    subscript(num: Int) -> Int {
        var decimalBase = 1
        
        for _ in 0..<num {
            decimalBase *= 10
        }    
        return (self / decimalBase) % 10  
    }
}

123456789[0] 

5. 중첩 타입 (Nested Type)

클래스, 구조체 및 열거형에 새 중첩 유형을 추가할 수 있습니다.
예를 들어, 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
        }
    }
}

0개의 댓글