[Swift5] Initialization 1

26483 단어 swiftswift
  • 다음은 Swift 5.6 Doc의 Initialization 공부 내용을 정리했음을 밝힙니다.

Initialization

초기화-이니셜라이제이션은 사용할 클래스, 구조체, 열거형 인스턴스를 사용하기 위해 준비하는 과정이다. 저장 프로퍼티에 사용할 초깃값을 설정학호 새로운 인스터스를 사용하기 전에 필요한 것 역시 초기화다.

이니셜라이저를 통해 초기화가 가능하다. 값을 리턴하지는 않고 처음 사용되기 전에 새로운 인스턴스 타입과 일치하는지 보장하는 역할이다.

클래스 인스턴스는 디이니셜라이저로도 사용할 수 있다.

저장 프로퍼티 초깃값 설정

클래스와 구조체 인스턴스는 생성 전에 모든 저장 프로퍼티에 대한 초깃값을 설정해야 한다. 이니셜라이저 또는 디폴트 프로퍼티 값을 통해 설정할 수 있다. 이때 프로퍼티 값은 프로퍼티 옵저버를 호출하지 않고 설정된다.

이니셜라이저

이니셜라이저는 특정 타입 인스턴스를 새로 생성할 때 호출할 수 있다. 파라미터 없는 인스턴스 메소드 init처럼 사용할 수 있다.

init() {
    // perform some initialization here
}
struct Fahrenheit {
    var temperature: Double
    init() {
        temperature = 32.0
    }
}
var f = Fahrenheit()
print("The default temperature is \(f.temperature)° Fahrenheit")
// Prints "The default temperature is 32.0° Fahrenheit"

Fahrenheit 클래스의 온도 디폴트 값은 32다.

디폴트 프로퍼티 값

이니셜라이저 안의 저장 프로퍼티 초깃값을 설정할 수 있지만, 디폴트 프로퍼티 값을 프로퍼티를 선언할 때 줄 수도 있다.

struct Fahrenheit {
    var temperature = 32.0
}

일반적으로 디폴트 값이 자주 사용된다면 init보다 사용이 편리하다.

초기화 커스터마이징

입력값 파라미터와 옵셔널 프로퍼티 타입을 통해 초기화를 커스터마이징할 수 있다. 또는 상수 프로퍼티를 할당할 수도 있다.

초기화 파라미터

초기화 과정에서 파라미터를 통해 값 타입과 이름을 설정할 수 있다.

struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0

Celsius 인스턴스 초기화 파라미터로 어떤 값을 주냐에 따라서 init되는 값이 달라진다.

파라미터 이름 및 아규먼트 라벨

초기화 파라미터는 초기화 내부에서 사용하는 파라미터 이름과 이니셜라이저를 호출할 때 사용하는 아규먼트 라벨 모두를 사용할 수 있다. 스위프트는 아규먼트 라벨을 붙이지 않는다면 자동으로 모든 초기화 파라미터에 대한 아규먼트 라벨을 붙여준다.

struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
    init(white: Double) {
        red   = white
        green = white
        blue  = white
    }
}

let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)

let veryGreen = Color(0.0, 1.0, 0.0)
// this reports a compile-time error - argument labels are required

아규먼트 라벨이 따로 설정된 초기화 init이 있다면 정확한 아규먼트 라벨을 전달해야 한다.

아규먼트 라벨 없이 초기화 파라미터 사용

아규먼트 라벨을 필요하지 않으면 언더스코어 _를 쓰면 된다.

struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
    init(_ celsius: Double) {
        temperatureInCelsius = celsius
    }
}
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius is 37.0

아규먼트 라벨을 사용하지 않는, 즉 언더스코어 _로 파라미터에 값을 주는 init 초기화가 사용될 수 있다.

옵셔널 프로퍼티 타입

저장 프로퍼티 값이 옵셔널하다면, 즉 널일 수도 있다면 옵셔널로 선언해야 한다. 값을 주지 않으면 디폴트 값으로 널 값이 할당된다.

class SurveyQuestion {
    var text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
// Prints "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese."

response 프로퍼티는 사전에 값을 정할 수 없기 때문에 옵셔널로 설정하는 게 적절하다.

초기화 중 상수 프로퍼티 할당

초기화 도중 어떤 시점이더라도 상수 프로퍼티 값을 할당할 수 있다. 상수 프로퍼티가 할당되면 수정할 수 없다.

클래스 인스턴스에서는 상수 프로퍼티를 사용하는 클래스만 초기화 도중 바꿀 수 있다. 서브클래스에서는 변경할 수 없다.

class SurveyQuestion {
    let text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let beetsQuestion = SurveyQuestion(text: "How about beets?")
beetsQuestion.ask()
// Prints "How about beets?"
beetsQuestion.response = "I also like beets. (But not with cheese.)"

text 상수는 처음 init으로 초기화할 때 준 값으로 설정된다.

디폴트 이니셜라이저

파라미터를 주지 않을 때 디폴트 값으로 설정한 인스턴스를 생성하는 디폴트 이니셜라이저가 있다.

class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()

item 인스턴스는 디폴트 이니셜라이저로 선언되었기 때문에 디폴트 값으로 세팅된다. name 역시 옵셔널 널 값이다.

구조체의 멤버와이즈 이니셜라이저

구조체 인스턴스를 생성할 때 커스텀 이니셜라이저가 없다면 멤버와이즈 이니셜라이저를 받는다. 디폴트 이니셜라이저와 달리 디폴트 값이 없는 저장 프로퍼티가 있어도 멤버와이즈 이니셜라이저가 필요하다.

struct Size {
    var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
let zeroByTwo = Size(height: 2.0)
print(zeroByTwo.width, zeroByTwo.height)
// Prints "0.0 2.0"

let zeroByZero = Size()
print(zeroByZero.width, zeroByZero.height)
// Prints "0.0 0.0"

디폴트 값이 있다면 멤버와이즈 이니셜라이저를 사용할 때에 생략할 수 있다. Size 구조체는 너비와 높이가 디폴트 값이 있는데, 이때 멤버와이즈를 주지 않으면 자동으로 디폴트 값이 들어간다.

값 타입에 대해 이니셜라이저 딜리게이션

이니셜라이저 딜리게이션을 통해 여러 개의 이니셜라이저 간의 중복 코드 사용을 줄일 수 있다. 값 타입, 클래스 타입마다 딜리게이션 사용 방법이 다르다. 구조체 및 열거형 등 값 타입은 상속을 지원하지 않지만 클래스는 다른 클래스를 상속 가능하다. 상속을 지원하기 때문에 클래스는 초기화를 사용할 때 상속하는 저장 프로퍼티 값이 모두 적절한 값을 가지도록 해야 한다.

값 타입을 사용할 때에는 self.init을 같은 값 타입에서 이니셜라이저를 언급할 때 사용할 수 있다. self.init은 초기화 블록 안에서만 언급 가능하다.

값 타입을 디폴트 이니셜라이저 또는 멤버와이즈 이니셜라이저로 초기화하고 싶다면 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()
    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)
    }
}

디폴트 이니셜라이저 init()은 너비와 높이, 크기 등이 모두 0인 기본 값으로 설정한다.

let basicRect = Rect()
// basicRect's origin is (0.0, 0.0) and its size is (0.0, 0.0)

let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
                      size: Size(width: 5.0, height: 5.0))
// originRect's origin is (2.0, 2.0) and its size is (5.0, 5.0)

let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)

init(center:size:) 이니셜라이저는 center로 받은 Point를 프로퍼티를 사용해 또 다른 값을 만들어낸다 (함수 역할).

좋은 웹페이지 즐겨찾기