구조체와 클래스의 초기화 방법에 대해 작성했습니다.
구조체를 초기화하는 방법은 다움과 같습니다.
우선 초기화라는 용어에 대해 알아보면!
초기화란, 구조체, 열거형, 클래스의 인스턴스를 생성하는 것입니다.
초기화의 역할은 모든 프로퍼티를 기본값으로 초기화하는 것이며, 인스턴스 내에 기본값이 존재하지 않는 프로퍼티가 있을 경우 초기화에 실패하고, 인스턴스는 생성되지 않습니다.
정리하자면, 초기화함수가 종료되기 전까지 구조체, 클래스 내에 있는 모든 속성값들을 기본값으로 초기화해야한다는 것입니다!
struct People {
let name: String = "nayeon"
let age: Int = 23
}
변수를 선언함과 동시에 기본값을 넣어 초기화하는 방법입니다.
struct People {
let name: String?
let age: Int?
}
프로퍼티를 옵셔널로 설정하면, 자동으로 nil로 초기화됩니다.
struct People {
let name: String?
let age: Int?
init(name: String) {
self.name = name
self.age = 23
}
}
init함수, 즉 생성자를 통해 초기화를 진행할 수 있는데요. 프로퍼티에 직접 값을 넣지 않고 생성자에서 프로퍼티를 초기화할 수 있습니다 .
구조체는 사실 init도 작성하지 않고, 프로퍼티에 값을 넣어주지 않아도 에러가 나지 않습니다. 구조체는 Memberwise intializer라는 초기화를 기본적으로 제공하고 있기 때문인데요.
인스턴스의 생성을 위해 init 시 무조건 프로퍼티의 값을 설정할 수 있도록 구조체에서 생성자를 자동으로 제공합니다.
struct People {
let name: String
let age: Int
}
이렇게 init 함수도 작성하지 않았고, 프로퍼티에 값도 넣어주지 않았습니다. 한번 확인해볼게요!

코파일럿 쓰니까 밑에 자동으로 뜨는데 무시해주세요
이 init함수를 통해 초기화를 진행할 수 있습니다. 대신 여기서 주의할 점이 있는데요!
바로 프로퍼티가 선언된 순서를 지켜야한다는 점입니다. name → age 순으로 선언했는데, 초기화 파라미터에 age, name 이렇게 쓰게 되면 에러가 납니다.
또한, 생성자를 구조체 안에서 직접 만든 경우 memberwise initializer는 제공되지 않습니다!
클래스를 초기화하는 방법은 다음과 같습니다. 큰 틀은 구조체와 비슷하지만, 몇가지 차이점이 있습니다.
class People {
let name: String = "nayeon"
let age: Int = 23
}
변수를 선언함과 동시에 기본값을 넣어 초기화하는 방법입니다.
class People {
var name: String?
var age: Int?
}
프로퍼티를 옵셔널로 설정하면, 자동으로 nil로 초기화됩니다.
대신! let은 옵셔널로 선언할 수 없습니다. 왜냐하면, class는 memberwise initializer가 제공되지 않기 때문입니다. let은 값을 바꿀 수 없는데, 옵셔널로 선언하게 되면 nil 외에는 값을 가질 수 없고, 심지어 값을 나중에 다시 생성해줄 수도 없기 때문입니다.
struct People {
let name: String?
let age: Int?
init(name: String) {
self.name = name
self.age = 23
}
}
init함수, 즉 생성자를 통해 초기화를 진행할 수 있는데요. 프로퍼티에 직접 값을 넣지 않고 생성자에서 프로퍼티를 초기화할 수 있습니다.
이 방식으로 서브클래스 초기화를 하는 경우, 반드시 슈퍼클래스의 initializer를 호출해주어야 합니다.

모든 프로퍼티를 초기화하는 init 이니셜라이저(Designated Initializers)를 도와주는 역할입니다. init 이니셜라이저의 파라미터 중 원하는 값을 기본값으로 설정하는 방식입니다. 어쨌든 도와주는 역할이기 때문에 init 이니셜라이저는 필수적으로 구현되어야 합니다.

Convenience Initializers 가 불리는 순서인데요. 모로 가든 init 이니셜라이저가 마지막에 불리게 됩니다. 예제로 볼게요.
class Person {
var name: String
var age: Int
init(name: String, age: Int){
self.name = name
self.age = age
}
convenience init(name: String){
self.init(name: name, age: 100)
}
convenience init(){
self.init(name: "unknown", age: 100)
}
}

여기 보시면 편의생성자가 2개 생성되어있는데요.
편의 생성자 안에서는 self.init으로 init 이니셜라이저를 부르고 있습니다.
name이 파라미터에 있는 생성자랑, 파라미터에 아무것도 없는 생성자가 있습니다.
편의 생성자는 기본값을 설정해주는 생성자라고 이해하면 좀 더 쉬운데요.


이렇게 3개의 객체를 생성해봤습니다. nayeon 객체에는 name, age를 다 줬고, hyoeun 객체에는 name만, person객체에는 아무것도 주지 않았습니다.
생성자에 들어간 파라미터에 따라 각기 다른 생성자가 불리게 된 것입니다.