본문 바로가기
iOS/Swift

[iOS/Swift] Extension(확장)을 통한 타입에 새로운 기능 부여하기

by iosdevlime 2023. 3. 23.

오랜만에 Swift 문법 포스팅으로 돌아왔습니다🥳

 

요 근래 UIKit을 활용해 클론 프로젝트를 진행하다보니,

ViewController에 기능을 더하는 extension 기능을 자주 사용하게 되더군요!

 

해서, Extension에 대해 간단하게 살펴보는 포스팅을 시작해볼까 합니다.

 

 

 


 

 

 

Extension(확장)이란?

구조체, 클래스, 열거형, 프로토콜 타입새로운 '기능'을 추가

 

우리가 자주 사용하는 Chrome Browser에서의 확장 프로그램과 같이

기존에 이미 만들어진 무언가에 새로운 '기능'을 더하는 의미로 이해하시길 바랍니다.

 

Swift에서의 Extension은

클래스, 구조체, 열거형 등의 타입으로 만들어진 무언가에

프로퍼티, 메서드, 초기값을 확장시키는 기능을 가지고 있습니다.

 

심지어, 프로토콜(Protocol)이나 제네릭 타입 또한 확장이 가능하답니다!

 

 

Extension 선언방식

  • Extension이란 키워드와 함께 확장할 타입 이름을 선언하여 사용합니다.
    • 내부에는 추가할 기능(프로퍼티, 메서드, 초기값 등)을 작성합니다.
    • Swift 표준 라이브러리 타입 기능의 대부분은 extension으로 구현되어 있습니다.
      (원시 데이터 타입 : Int, String, Double 등)
extension 확장할 타입의 이름 {
 // 확장하고자 하는 기능 구현 (프로퍼티, 메서드, 초기값)
}

 

 

클래스의 상속(Inheritance)과의 차이

  • Extension은, 상속과는 달리 모든 타입에서 활용 가능합니다.
    • 클래스의 상속의 경우, '클래스' 타입에서만 기능을 확장할 수 있습니다.
    • 반면에, extension은 구조체, 클래스, 열거형 등 대부분의 타입을 확장합니다.

상속은 수직적 확장, Extension은 수평적 확장을 실시함
상속은 수직적 확장, Extension은 수평적 확장을 실시함

 

  • 다만, Extension은 Override(재 정의) 기능은 활용할 수 없습니다.
    • 이는 기존에 이미 만들어진 타입에 새로운 기능을 추가(New)하는 방식이기 때문입니다.
    • 따라서, 기존에 선언된 내부 기능은 재 정의가 불가능 합니다.

 


 

 

Extension(확장)이 타입에 추가하는 기능들

프로퍼티, 메서드, 이니셜라이저, 서브스크립트 등 다양한 기능 + 더하기

 

Extension을 통해 기존 타입에 다음과 같은 기능을 더할 수 있습니다.

  • 연산 프로퍼티
  • 타입 메서드, 인스턴스 메서드
  • initializer
  • Subscript
  • Nested Type

이번 파트에서는,

프로퍼티메서드를 추가하는 방법에 대해 알아보겠습니다.

(그 외 기능은 추후 관련 문법 포스팅에서 다루도록 하겠습니다)

 

 

 

첫 번째, 프로퍼티(연산 프로퍼티)

  • Extension은 메모리 이슈로 인해 '저장 프로퍼티'는 추가할 수 없습니다.
    • 해당 타입 내부에 그 외의 타입이 저장될 경우, 메모리의 크기나 역할이 불분명해집니다.
    • 따라서, Swift의 경우 애초에 Extension에서 저장 프로퍼티 선언을 할 수 없습니다.
  • 아래 코드는 Double 구조체 VAT(부가세)를 더하는 연산 프로퍼티를 선언한 예시입니다.
    • self 키워드는 Double 타입 자체를 가리키는 키워드입니다.
    • bill이란 Double 타입의 변수에 + 추가된 연산 프로퍼티(plusVAT)를 활용할 수 있습니다.
extension Double {
    var plusVAT: Double {
        return (self + Double(self * 0.1))
    }
}

// 변수 'bill'은 100.0이란 초기값을 가지고 있으며
let bill: Double = 100.0

// 위 extension을 통해 추가된 연산 프로퍼티 plusVAT를 불러온다면?
print(bill.plusVAT) // 110.0

 

 

 

두 번째, 메서드

  • 아래 코드는 CGSize란 구조체에 print 함수를 확장하는 예시입니다.
    • CGSize 타입은 너비와 높이를 가지고 있으며, view 인스턴스의 초기값을 설정합니다.
    • 이후, width: (  ) , height: (  )와 같이 결과를 출력하고자 print 구문을 작성합니다.
  • Extension을 통해 새로운 print 메서드(인스턴스 메서드)를 생성하여 호출할 수 있습니다.
    • CGSize 타입을 확장, printCGSize란 인스턴스 메서드를 새롭게 추가합니다.
    • view 인스턴스 에서 해당 메서드로 접근하여 원하는 출력 구문을 나타낼 수 있습니다.
let view: CGSize = CGSize(width: 30, height: 50) // CGSize란 타입을 채택, 너비와 높이의 초기값을 설정해 줌

// 근데, width: 30, height: 50 과 같이 깔끔하게 출력하고자 한다면,
// 아래와 같이 어렵게 작성해줘야 함
print("width: \(view.width), height: \(view.height)") // width: 30.0, height: 50.0

// 그런데, 위에서 언급한 대로 extension은 기존의 타입에서 새로운 '기능'을 추가하는 역할을 한다고 살펴보았음
// 즉, 'CGSize'란 이미 명명된 구조체 내부에 깔끔하게 출력할 수 있는 print 메서드를 추가하면 되지 않을까?

extension CGSize {
    func printCGSize() {
        print("width: \(width), height: \(height)")
    }
}

view.printCGSize() // width: 30.0, height: 50.0

 


 

추가적으로 다뤄야 할 Extension의 내용이 더 많지만😳

 

아직 다루지 않은 개념과 함께 살펴보는 건 무리라 생각하여 

간단히 메서드, 프로퍼티 추가 기능만 다뤄보았습니다.

 

남은 궁금증을 해소할 수 있도록, 빠르게 다음 포스팅으로 돌아오겠습니다!

댓글