[Swift 프로그래밍] 익스텐션 (extension)

이정훈·2023년 1월 25일
0

Swift 기본

목록 보기
20/22
post-thumbnail

본 내용은 스위프트 프로그래밍 3판 (야곰 지음) 교재를 공부한 내용을 바탕으로 작성 하였습니다.

익스텐션(extension)의 정의


익스텐션(extension)은 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가 해주는 문법이다.

스위프트 타입에 익스텐션을 추가 할 수 있는 기능은 다음과 같다.

  • 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티
  • 타입 메서드 / 인스턴스 메서드
  • 이니셜라이저
  • 서브스크립트
  • 중첩 타입(타입 안의 타입)
  • 프로토콜

또한 상속과 익스텐션의 차이는 상속은 기능을 물려 받아 재정의 하거나 새로운 기능을 추가 할수 있지만, 익스텐션은 기능 추가의 역할만 담당하고 새롭게 재정의 하지는 못한다는 것이다.

extension을 사용하는 이유?

그렇다면 원본 클래스나 구조체, 프로토콜에 기능을 추가하면 되지 왜 우리는 extension을 사용 해야될까?

우리가 만약 외부에서 라이브러리나 프레임워크를 가져다 사용한다면 원본 소스를 수정할 수 없다. 따라서 외부 라이브러리나 프레임워크를 가져와서 extension으로 기능을 확장해서 쓸수 있으며, 또한 extensionprotocol과 연계하여 아주 강력한 기능을 할 수 있다.
extension과 protocol의 관계에 대해서는 다음에 따로 포스트로 정리하려고 한다.

extension 문법

익스텐션의 구현은 extension 키워드를 사용하여 구현하며, 형태는 다음과 같다.

extension 확장할 타입 이름 {
	기능 구현
}

익스텐션으로 추가할 수 있는 기능

1. 연산 프로퍼티

다음은 익스텐션으로 연산 프로퍼티 기능을 추가하는 코드이다.

extension Int {
    var multipleOfTwo: Bool {   //2의 배수인지 확인하는 연산 프로퍼티
        return self % 2 == 0
    }
    
    var multipleOfFive: Bool {  //5의 배수인지 확인하는 연산 프로퍼티
        return self % 5 == 0
    }
}

var number: Int = 6
print(number.multipleOfTwo)     //true
print(number.multipleOfFive)    //false

number = 10
print(number.multipleOfTwo)     //true
print(number.multipleOfFive)    //true

Int 타입에 2의 배수와 5의 배수를 확인하여 Bool 타입을 반환하는 multipleOfTwomultipleOfFive 연산 프로퍼티를 추가하였다.

extension을 통해 위의 예시와 같이 연산 프로퍼티를 추가할 수는 있지만 저장 프로퍼티는 추가할 수 없으며, 프로퍼티 감시자 또한 추가할 수 없다.

2. 메서드 추가

다음은 익스텐션으로 메서드를 추가한 코드이다.

extension Int {
    var multipleOfTwo: Bool {   //2의 배수인지 확인하는 연산 프로퍼티 추가
        return self % 2 == 0
    }
    
    var multipleOfFive: Bool {  //5의 배수인지 확인하는 연산 프로퍼티 추가
        return self % 5 == 0
    }
    
    func squared() -> Int {    //제곱을 만들어주는 메서드 추가
        return self * self
    }
    
    //Int Type인지 확인하는 타입 메서드 추가
    static func isIntTypeInstance(_ instance: Any) -> Bool {
        return instance is Int
    }
}

var number: Int = 6
print(number.multipleOfTwo)     //true
print(number.multipleOfFive)    //false
print(number.squared())         //36
print(Int.isIntTypeInstance(number))    //true

number = 10
print(number.multipleOfTwo)     //true
print(number.multipleOfFive)    //true
print(Int.isIntTypeInstance(number))    //true

제곱을 만들어주는 squared() 인스턴스 메서드와 인스턴스가 Int 타입인지 확인하는 isIntTypeInstance 타입 메서드를 추가 하였다.

3. 이니셜라이저 추가

이니셜라이저를 추가하여 인스턴스를 초기화할때 데이터를 받아 오도록 추가할 수 있다.

여기서 클래스에 익스텐션으로 이니셜라이저를 추가할때 주의 할 점은 편의 이니셜라이저는 추가 할 수 있지만 지정 이니셜라이저는 추가 할 수 없다는 점이다.

지정 이니셜라이저는 반드시 클래스 구현부에서 구현해야한다.

extension String {      //이니셜라이저 추가
    init(name: String) {
        self = name + "님"
    }
}

let personLeeName: String = String(name: "이철수")
print(personLeeName)	//이철수님

class Person {
    var name: String
    
    init(name: String) {
        self.name = name
    }
}

extension Person {
    convenience init() {    // 편의 이니셜라이저 추가
        self.init(name: "Unkown")
    }
}

let somePerson: Person = Person()
print(somePerson.name)	//Unkown

4. 서브스크립트 추가

익스텐션으로 서브스립트를 추가할 수 있다.

 extension String {
    subscript(repeatCount: Int) -> String {
        var str: String = ""
        for _ in 0..<repeatCount {
            str += self
        }
        return str
    }
}

print("hello"[3])

서브스크립트로 Int 타입 매개변수를 받아서 그 숫자만큼 문자열을 반복출력하는 코드를 구현하였다.

profile
새롭게 알게된 것을 기록하는 공간

0개의 댓글