TIL 0107 - Extensions 계산 속성 확장, 생성자 확장

ian·2022년 1월 7일
0

TIL

목록 보기
5/11
post-thumbnail

Extension 에 대해서.. 할 말이 너무 많고 넘치는데 !

일단 오늘은 계산 속성의 확장, 생성자 확장에 대해 공부해봤음!


먼저 계산 속성의 확장을 봐보자.

난 인스턴스의 계산 속성을 기존의 애플이 만든 Double 타입에 추가하는 예제를 만들건데,
자신의 단위를 입력하여 -> 미터 기준으로 바꾸는 예제를 만들거임!

extension Double {
    var km: Double { return self * 1_000.0 }   // 인스턴스 자신에 1000 곱하기
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}


let oneInch = 25.4.mm
print("1인치는 \(oneInch) 미터")       // 1인치는 0.0254 미터"


let threeFeet = 3.ft
print("3피트는 \(threeFeet) 미터")     // 3피트는 0.914399970739201 미터"

25.4 , 3 등은 Double 타입이므로 ! 우리가 확장한 부분을 명확하게 구현할 수 있다!
인스턴스자체에 즉, Double의 리터럴값에 .(점)문법을 사용하여 거리 변환을 수행하도록 만들어 봤어요

만약, 간단한 Int 관련 된 걸 extension 확장으로 구현을 하지 않고 함수로 구현을 한다면?

func squared(num: Int) -> Int {    
    return num * num
}

squared(num: 123)

과 같이 구현할 수 있지만, 확장으로 한 번 훑어보겠음!

extension Int {
    var squared: Int {
        return self * self  
    }
}

123.squared

이런식으로 구현할 수 있는데! 난 이 방식이 좀 더 좋은 것 같다.. 근데.. 뭐 그때그때 보면서 고르기 !


생성자 확장의 예시 (클래스) 에선!

UIColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
UIColor(red: 0.24, green: 0.2, blue: 0.8, alpha: 1)

원랜! 위와 같이 세세하게 숫자를 기입하고 그래야했지만..

extension UIColor {      // 익스텐션 + 편의생성자 조합
    convenience init(color: CGFloat) {   // Float   / Double
        self.init(red: color/255, green: color/255, blue: color/255, alpha: 1)
    }
}

UIColor(color: 1)

extension 을 이용해 밑처럼 간단하게 표현할 수 있도록 구현할 수 있습니다!

클래스에선

  • 편의 생성자만 추가 가능
  • 지정생성자 추가 불가 / 소멸자 추가 불가 (항상 본래의 클래스에서 정의해야 함)

그럼 다음으로! 구조체에선 생성자 확장은 어떨까?

struct Point {
    var x = 0.0, y = 0.0
}

// 만약 확장을 통해 구현한다면

extension Point {
    init(num: Double) {
        self.init(x: num, y: num)
    }
}

// 구조체 같은 경우엔 멤버와이즈 이니셜라이징, 기본 생성자가 자동으로 구현하여 구조체에 init(x,y) / init() 을 구현

struct Size {
    var width = 0.0, height = 0.0
}

// Rect구조체
struct Rect {     // 기본값 제공 ===> 기본 생성자 / 멤버와이즈 생성자가 자동 제공 중
    var origin = Point()
    var size = Size()
}

let defaultRect = Rect()    // 기본생성자
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
                          size: Size(width: 5.0, height: 5.0))    // 멤버와이즈 생성자

extension Rect {
    // 센터값으로 Rect 생성하는 생성자 만들기
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        
        // 본체의 - 멤버와이즈 생성자 호출 (원칙) ⭐️
        self.init(origin: Point(x: originX, y: originY), size: size)
        
        // 예외적인 경우 (저장속성에 기본값 + 본체에 생성자 구현 안한 경우, 생성자 구현 가능)
        //self.origin = Point(x: originX, y: originY)
        //self.size = size
    }
}

let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))

구조체에선

  • 구조체는 (원래) 편의 생성자가 존재하지 않음
  • (편의 생성자와 비슷한) 생성자를 추가하여 본래의 지정 생성자를 호출하는 방법으로만 구현 가능
  • (본체) 생성자 작성
  • 기본 생성자/멤버와이즈 생성자 제공 안됨
  • 확장의 생성자에서 ===> (본래) 지정 생성자 호출해야함
  • (예외) (본체) 저장속성에 기본값제공 + 생성자 정의 안한 경우
  • 기본 생성자/멤버와이즈 생성자가 자동제공
  • 확장의 생성자에서 ===> 생성자 구현 가능 ⭐️ / 기본 생성자/멤버와이즈 생성자 호출도 가능

하다는 걸 알 수 있음 !!


학습 키워드

  • 계산 속성의 확장
  • 생성자 확장

문제점 / 고민한 점

  • 생성자에 대해 완벽하게 이해를 못하고 있으니 .. 약간 이해가 안되는 느낌? 강의를 한 번 더 훑고 다시 깊게 봐야겠다..

TIL 시리즈는 막연히 제가 배운 걸 기록하는 공간입니다.


출처:
앨런 swift 문법 마스터 스쿨

profile
디자인씽킹을 하며 iOS 를 공부합니다

0개의 댓글