티스토리 뷰

728x90
반응형

Swift Docs의 Initialization 과 Extensions을 읽으며 알게 된 내용이다. 

 

Swift의 Structure은 자동으로 default initializer와 memberwise initializer를 가지게 된다.

다만 custom initializer를 따로 정의하지 않았을 때만!! 

 

예제를 통해 살펴보자.

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

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

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))

 

Rect에 custom initializer 를 추가하게 되면 

자동으로 제공되던 default initializer, memberwise initializer 를 개발자가 직접 구현해줘야한다는 것이다. 

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

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

struct Rect {
    var origin = Point()
    var size = Size()
    
    init() {}
    
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    
    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)
    }
}


let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
                          size: Size(width: 5.0, height: 5.0))
let customRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))

 

하지만 default initializer, memberwise initializer 자동생성을 그대로 유지하면서 

custom initializer 를 추가하는 방법이 있는데, custom initializer 를 extension 에 작성하면 된다. 

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

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

struct Rect {
    var origin = Point()
    var size = Size()
}

extension 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)
    }
}

let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
                          size: Size(width: 5.0, height: 5.0))
let customRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))

 

이런 방법이 있는 줄 몰랐다!! 😮

하지만 나는 이니셜라이저는 extension이 아니라 original implementation 에 있는게 좋다고 생각한다. 

 

+

외부 모듈에 있는 모델에 대해 커스텀 이니셜라이저를 추가한다고 할 때, 

extension으로 커스텀 이니셜라이저를 작성할텐데 그 때 기존 구현이 깨지면 안되기 때문에

당연한 것 같기두..?

 

 

 

 

 

 

 

 

 

 

반응형
댓글