티스토리 뷰

이니셜라이져(initializer)를 줄여서 생성자로 불렀습니다.

 

초기화와 생성자는 하나의 포스팅으로 다루기엔 범위도 넓고 알게 많기 때문에 크게 3부로 나누었다.

1부에서는 초기화, 생성자가 무엇인지와 구조체의 초기화, 실패가능 생성자(구조체와 열거형에서 사용)에 대해서

2부에서 지정생성자와 편의생성자를 중점적으로 힘주어 다루며

3부에서는 필수생성자와 소멸자, 실패가능생성자(클래스에서 사용)를 다룬다.

INDEX

1.  초기화(Initialization)란?

2.  구조체의 초기화 - Memberwise Initializer?

3. 실패가능 생성자(Failable Initializer with sturct and enum)

4. 마무리

 

1.  초기화(Initialization)란?

초기화(Initialization)란 클래스, 구조체, 열거형의 인스턴스를 생성하는 과정으로

모든 저장속성에 대한 초기값을 설정하여 인스턴스를 사용가능한 상태로 만드는 것을 뜻한다.

(물론 열거형은 저장속성이 따로존재 X, case중 한가지를 선택하여 생성)

생성자(init함수)의 역할은 무엇인가?

인스턴스의 모든 저장속성의 초기값을 셋팅한다

 

//🍎공식문서 예제

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"

 

초기화(Initialization) 방법

 1) 저장 속성의 선언과 동시에 값 저장하기 

 2) 저장 속성을 옵셔널로 선언하기 (초기값이 없어도 nil로 초기화된다. 개꿀☺️)

 3) 생성자에서 값을 초기화하기

추가적으로 알면 좋은 사항

1. 따로 생성자를 구현해주지 않아도 컴파일러는 기본 생성자(Default Initializer)를 자동 생성한다. init()

2. 생성자도 오버로딩을 지원한다.(아래 코드 참조)

 

struct Color {
    let red, green, blue: Double //동일한 타입일때, 한줄에 작성가능
    
    // 생성자도 오버로딩(Overloading)을 지원 (파리미터의 수, 아규먼트 레이블, 자료형으로 구분)
 
    init() {      // "init()" -> 기본 생성자. 저장 속성의 기본값을 설정하면 "자동" 구현이 제공됨
        red = 0.0
        green = 0.0
        blue = 0.0
    }
    
    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
    }
}

아래와 같이 자동구현되며 오버로딩을 지원한다.

 

 

 

2.  구조체(Struct)의 초기화 - Memberwise Initializer?

클래스에 비하여 구조체는 초기화 방법은 매우 간단하기에 이번 포스팅에서만 다룬다.

구조체에는 지정생성자와 실패가능생성자만 존재한다.

 

구조체의 생성자 정의(4가지 방법)

//1. 선언과 동시에 기본값 설정

struct Color1 {
    var red: Double = 1.0
    var green: Double = 1.0
    var blue: Double = 1.0
}

//2. 속성 타입을 옵셔널로 설정

struct Color2{
    var red: Double?
    var green: Double?
    var blue: Double?
}

//3. init()에서 설정

struct Color3{
    var red: Double
    var green: Double
    var blue: Double
    init(red: Double) {
        self.red = red
        self.green = 1.0
        self.blue = 1.0
    }
}

//4. class와 달리 초기화해주지 않아도된다.WHY? Memberwise Initializers

struct Color4{
    var red: Double
    var green: Double
    var blue: Double
}

 

난 class!! 초기화가 필요해

⭐️구조체의 Memberwise Initializer⭐️

 

Memberwise : 멤버에 관하여 ( ~wise : ~에 관하여)

구조체가 자동으로 제공하는 생성자

구조체 내에서 각 속성에 대한 초기화를 해주지 않더라도, 멤버에 관한 생성자를 제공

물론 개별적으로 구조체내에서 생성자를 구현한다면, Memberwise Initializer는 자동으로 제공되지 않는다.(편의적 기능)

 

그렇다면 WHY 구조체에만 Memberwise Initializer가 있고, 클래스에는 없을까?

구조체는 클래스에 비해 가벼운 데이터묶음을 다룰때 용이하며 쉽게 쓸 수 있기 때문에,

클래스보다 더편하게 쓰기 위해서이고,

클래스에는 없는 이유는 생성자가 '상속'과 관련이 있기 때문에 Memberwise Initializer가 있다면 더 복잡해질 것이다.

Memberwise Initializer

하지만 Memberwise Initializer생성되지 않는 경우가 존재한다.

1. 구조체에서 정의한 속성(프로퍼티)순서와 파라미터의 순서가 다를때

2. 프로퍼티가 let선언에 초기화가 되었을때 

3.생성자를 직접 재정의할때 

4.속성중 하나가 private선언되어 있을때

 

struct Color4{
    var red,green,blue : Double
    let yellow = 3.0 //2번경우
    //private var orange: Double //4번경우
    
    //3번경우
//    init(red: Double, green: Double) {
//        self.red = red
//        self.green = green
//        self.blue = 2.0
//    }
}

//var myColor = Color4(green:1.0,red:1.0,blue:1.0) //1번경우

 

3. 실패가능생성자(Failable Initializer) 

 

실패가능생성자는 뒤에 따로 포스팅하겠지만, 구조체를 통해 미리 소개하고자한다. 구조체는 상속관계가 없기에 실패가능 생성자를 이해하기 더 쉽다.

 

실패가능생성자(Failable Initializer)란?

인스턴스 생성에 실패할 수도 있는 가능성을 가진 생성자(클래스, 구조체, 열거형 가능)

생성자(Initializer)를 정의할때 실패가능성을 염두해둠으로써 실패를 불가능하게 만든다

(옵셔널과 nil을 생각하면 이해하기쉽다)

실패가능한생성자는 생성 실패시 nil을 리턴해주는 반환타입이 옵셔널이다.

사용 이유? -> 생성자 오류로 에러가 발생해 앱이 꺼지지 않게 하기 위해서

init?

 

구조체의 실패가능생성자

 

//🍎공식문서 예제

struct Animal {
    let species: String
    
    // 실패가능 생성자
    init?(species: String) {
        if species.isEmpty {
            return nil            // 생성자 내에서 실패 가능 부분에 nil을 리턴하면 됨  (문법적 약속)
        }
        self.species = species
    }
    
}

let a = Animal(species: "Giraffe")    // ====> 인스턴스 생성
let b = Animal(species: "")           // 문자열이기에 유효한 타입이지만 =====> nil

// 초기화 성공을 나타 내기 위해 return 키워드를 사용하지 않음 (문법적 약속)

 

열거형에서 실패가능 생성자

//🍎공식문서 예제

enum TemperatureUnit {
    case kelvin, celsius, fahrenheit
   init?(symbol: Character) {
        switch symbol {
        case "K":
            self = TemperatureUnit.kelvin
        case "C":
            self = TemperatureUnit.celsius
        case "F":
            self = TemperatureUnit.fahrenheit
        default:
            return nil
        }
    }
}

let f = TemperatureUnit(symbol: "F") 
if f != nil {
    print("This is a defined temperature unit, so initialization succeeded.")
}
// Prints "This is a defined temperature unit, so initialization succeeded."

let x = TemperatureUnit(symbol: "X")
if x == nil {
    print("This is not a defined temperature unit, so initialization failed.")
}
// Prints "This is not a defined temperature unit, so initialization failed."

let c: TemperatureUnit = TemperatureUnit.celsius      // TemperatureUnit()
let f: TemperatureUnit? = TemperatureUnit(symbol: "F")

// 열거형의 원시값 설정 (실패가능 생성자의 구현과 유사)

enum TemperatureUnit1: Character {
    case kelvin = "K"
    case celsius = "C"
    case fahrenheit = "F"
}

// 원시값이 있는 열거형은 자동으로 실패가능 생성자 init?(rawValue :)를 구현함 ==> 일치하면 인스턴스 생성, 아니면 nil

 
let f1: TemperatureUnit1? = TemperatureUnit1(rawValue: "F")     // .fahrenheit

let u: TemperatureUnit1? = TemperatureUnit1(rawValue: "X")      // nil

 

클래스의 실패가능생성자는 상속관계가 있기에, 다른 생성자들의 설명이 끝나고 상속이 익숙해진 끝부분에서 다루기로한다.

 

4. 마무리

이번 포스팅은 초기화와 생성자가 무엇인지 간단히 설명했고,

구조체에 존재하는 2가지 생성자인 지정생성자(특히 Memberwise Initializer)와 실패가능 생성자(struct와 enum타입까지)를 다루었고 어렵지 않은 개념이기에, 쉽게 기억에 남을 것이다.

이로써 구조체의 생성자는 끝이며 2부 부터는 클래스만 다룬다.

클래스에도 이 2개의 생성자가 있으며, 편의 생성자와 필수생성자로 총4개가 존재하며 모두 상속과 관련이 있기에 구조체보다는 까다로운게 사실이다. 그래도 하지만 한번 제대로 배워 놓으면 상속을 다룰때 편해질 것이며, 객체지향의 관점으로 Swift에 더 접근할 수 있을 것이다.

 

출처

Inflearn Allen님의 강의 노트

Swift 공식문서

야곰님의 스위프트 프로그래밍 3판

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함