Menu
CoddyTech

Initializer yang Bisa Gagal

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Swift di Coddy. Pelajaran 20 dari 57.

Beberapa nilai tidak dapat dibuat dari setiap input. Initializer yang dapat gagal, ditulis init?, mengembalikan nil alih-alih sebuah instance ketika input tidak valid, sehingga instance yang tidak valid tidak akan pernah ada:

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)

Output:

42
-1

Hasil dari initializer yang dapat gagal adalah optional, jadi pemanggil harus membuka bungkusnya, biasanya dengan if let atau 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)")
    }
}

Output:

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

Tipe bawaan Swift menggunakan gagasan yang sama: Int("42") dan Double("x") adalah initializer yang bisa gagal, begitu juga init(rawValue:) milik enum. Initializer yang bisa gagal dapat memanggilnya dan meneruskan kegagalannya:

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)

Output:

true
false

Gunakan init? saat nilai yang tidak ada sudah cukup sebagai informasi. Gunakan initializer yang melemparkan error, init(...) throws, saat pemanggil perlu mengetahui aturan mana yang gagal:

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

Tantangan

Mudah

Lengkapi struct Rgb, yang menyimpan warna sebagai red, green, dan blue dari 0 hingga 255. Initializer yang dapat gagal, init?(hex:), membaca teks seperti #FF8000: initializer ini mengembalikan nil kecuali teks tersebut berupa # yang diikuti tepat enam digit heksadesimal. Gunakan Int(text, radix: 16) untuk setiap pasangan digit. Tambahkan label terhitung yang mengembalikan rgb(255, 128, 0).

Kode yang disediakan membaca satu warna per baris dan mencetak label atau invalid: text.

Tulis kodemu di Rgb.swift. main.swift berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

// Kode input/output yang disediakan: biarkan apa adanya
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 iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Playground Swift