Menu
Coddy logo textTech

실패 가능한 초기화

Coddy Swift 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 20번째.

일부 값은 모든 입력으로 생성할 수 없습니다. 실패 가능한 이니셜라이저는 init?로 작성하며, 입력이 유효하지 않을 때 인스턴스 대신 nil을 반환하므로 유효하지 않은 인스턴스가 존재할 수 없습니다:

struct Percentage {
    let value: Int

    init?(_ value: Int) {
        guard value >= 0, value <= 100 else { return nil }
        self.value = value
    }
}

print(Percentage(42)?.value ?? -1)
print(Percentage(150)?.value ?? -1)

출력:

42
-1

실패 가능한 이니셜라이저의 결과는 옵셔널이므로, 호출자는 일반적으로 if let 또는 guard let을 사용해 언래핑해야 합니다:

struct Email {
    let address: String

    init?(_ text: String) {
        let parts = text.split(separator: "@")
        guard parts.count == 2, parts[1].contains(".") else { return nil }
        address = text.lowercased()
    }
}

for text in ["Ada@Mail.com", "not-an-email"] {
    if let email = Email(text) {
        print("valid: \(email.address)")
    } else {
        print("invalid: \(text)")
    }
}

출력:

valid: ada@mail.com
invalid: not-an-email

Swift 자체 타입도 같은 개념을 사용합니다. Int("42")와 Double("x")는 실패 가능한 이니셜라이저이며, 열거형의 init(rawValue:)도 마찬가지입니다. 실패 가능한 이니셜라이저는 이러한 이니셜라이저를 호출하고 실패를 전달할 수 있습니다.

struct Coordinate {
    let lat: Double
    let lon: Double

    init?(text: String) {
        let parts = text.split(separator: ",")
        guard parts.count == 2,
              let lat = Double(parts[0]), let lon = Double(parts[1]),
              abs(lat) <= 90, abs(lon) <= 180 else { return nil }
        self.lat = lat
        self.lon = lon
    }
}

print(Coordinate(text: "51.5,-0.1") != nil)
print(Coordinate(text: "95,10") != nil)

출력:

true
false

값이 누락되었다는 사실만으로 충분한 정보일 때는 init?을 사용하세요. 호출자가 어떤 규칙이 실패했는지 알아야 할 때는 오류를 발생시키는 초기화 프로그램인 init(...) throws를 사용하세요:

struct Username {
    let text: String
    init(_ text: String) throws {
        guard text.count >= 3 else { throw NameError.tooShort }
        guard text.allSatisfy({ $0.isLetter }) else { throw NameError.badCharacters }
        self.text = text
    }
}
challenge icon

챌린지

쉬움

red, green, blue를 0부터 255까지의 값으로 색상을 저장하는 Rgb 구조체를 완성하세요. 실패 가능한 이니셜라이저 init?(hex:)는 #FF8000과 같은 텍스트를 읽습니다. 텍스트가 # 뒤에 정확히 6개의 16진수 숫자가 오는 형식이 아니면 nil을 반환합니다. 각 쌍에 Int(text, radix: 16)을 사용하세요. rgb(255, 128, 0)을 반환하는 계산된 label을 추가하세요.

제공된 코드는 한 줄에 하나씩 색상을 읽고 레이블 또는 invalid: text를 출력합니다.

코드는 Rgb.swift에 작성하세요. main.swift에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.

직접 해보기

// 제공된 입력/출력 코드: 그대로 유지하세요
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
    if let color = Rgb(hex: line) {
        print(color.label)
    } else {
        print("invalid: \(line)")
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: Swift 플레이그라운드