Latest web development tutorials

rantai opsional Swift

Opsional rantai (opsional Chaining) adalah adalah cara untuk meminta dan memanggil properti, pendekatan proses dan sub-script panggilan untuk permintaan target atau mungkin nihil.

rantai opsional mengembalikan dua nilai:

  • Jika target memiliki nilai, panggilan berhasil, nilai kembali

  • Jika target adalah nihil, panggilan akan kembali nil

Beberapa permintaan atau panggilan dapat dihubungkan ke sebuah rantai, jika ada node kegagalan nil akan menyebabkan seluruh rantai.


Opsional rantai alternatif tekad dipaksa

Dengan menambahkan properti, metode, atau opsional indeks nilai naskah menempatkan tanda tanya (?), Anda dapat menentukan rantai opsional.

Opsional chain '?' Tanda seru (!) Untuk memaksa metode ekspansi, properti, naskah subscript rantai opsional
? Sebuah nilai opsional ditempatkan pada metode, properti, naskah subscript kemudian memanggil ! Nilai Opsional ditempatkan pada metode panggilan kemudian, sifat, naskah subscript untuk memperluas nilai wajib
Ketika output opsional adalah nihil pesan kesalahan lebih ramah Ketika ekspansi opsional nihil dipaksa kesalahan eksekusi

Gunakan tanda seru (!) Contoh rantai opsional

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

//将导致运行时错误
let roomCount = john.residence!.numberOfRooms

Output di atas eksekusi program adalah:

fatal error: unexpectedly found nil while unwrapping an Optional value

Ingin menggunakan tanda seru (!) Untuk memaksa parsing orang ini tinggal nilai numberOfRooms properti properti, ia akan melempar kesalahan runtime, karena maka tidak ada nilai dapat digunakan untuk tempat tinggal diselesaikan.

Gunakan tanda seru (!) Contoh rantai opsional

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

// 链接可选residence?属性,如果residence存在则取回numberOfRooms的值
if let roomCount = john.residence?.numberOfRooms {
    print("John 的房间号为 \(roomCount)。")
} else {
    print("不能查看房间号")
}

Output di atas eksekusi program adalah:

不能查看房间号

Karena upaya ini numberOfRooms operasi mungkin gagal, rantai opsional akan kembali Int? Nilai Type, atau disebut "Opsional Int". Ketika tinggal itu kosong ketika (contoh), pilih Int akan kosong, sehingga tidak akan ada kasus numberOfRooms akses.

Perlu dicatat bahwa bahkan non-opsional numberOfRooms Int (Int?) Bila ini juga benar. Selama permintaan opsional rantai dengan cara numberOfRooms akhir selalu kembali Int? Sebaliknya Int.


Kelas model didefinisikan sebagai rantai opsional

Anda dapat menggunakan rantai opsional untuk sifat multi-panggilan, metode, dan script indeks. Hal ini memungkinkan Anda untuk menggunakan model yang kompleks antara mereka untuk mendapatkan lebih banyak sifat yang mendasari, dan memeriksa apakah Anda dapat memperoleh properti yang mendasari seperti.

contoh

Model mendefinisikan empat kelas, termasuk rantai multi-opsional:

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

Dengan metode rantai opsional panggilan

Metode untuk memohon pengaturan alternatif Anda dapat menggunakan rantai opsional dan memeriksa metode panggilan berhasil. Bahkan jika metode ini tidak mengembalikan nilai, Anda masih dapat menggunakan rantai opsional untuk mencapai tujuan ini.

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()


if ((john.residence?.printNumberOfRooms()) != nil) {
    print("输出房间号")
} else {
    print("无法输出房间号")
}

Output di atas eksekusi program adalah:

无法输出房间号

Gunakan jika pernyataan untuk memeriksa apakah metode panggilan printNumberOfRooms sukses: Jika metode panggilan berhasil melalui rantai opsional, printNumberOfRooms implisit nilai kembali akan Void, jika tidak berhasil, ia mengembalikan nil.


Menggunakan rantai opsional skrip panggilan subscript

Anda dapat menggunakan rantai opsional untuk mencoba untuk mendapatkan nilai dari script standar dan memeriksa naskah panggilan subscript berikutnya berhasil, namun Anda tidak dapat mengatur rantai indeks skrip opsional.

contoh 1

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()
if let firstRoomName = john.residence?[0].name {
    print("第一个房间名 \(firstRoomName).")
} else {
    print("无法检索到房间")
}

Output di atas eksekusi program adalah:

无法检索到房间

Script standar berikutnya panggilan rantai opsional tepat di belakang tanda tanya circname.print, script standar berikutnya kurung depan karena circname.print rantai opsional mencoba untuk mendapatkan nilai opsional.

contoh 2

Contoh kasus untuk membuat john.residence Residence, dan satu atau lebih contoh nya berbagai kamar Room, maka Anda dapat menggunakan rantai opsional untuk mendapatkan kamar dalam contoh array dengan skrip Hotel subscript:

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()
let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouse

if let firstRoomName = john.residence?[0].name {
    print("第一个房间名为\(firstRoomName)")
} else {
    print("无法检索到房间")
}

Output di atas eksekusi program adalah:

第一个房间名为客厅

Untuk mengakses indeks melalui opsional Link panggilan

Dengan opsional Link panggilan, kita dapat menggunakan indeks untuk dibaca atau ditulis ke nilai opsional, dan menentukan panggilan subscript berhasil.

contoh

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()

let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouse

if let firstRoomName = john.residence?[0].name {
    print("第一个房间名为\(firstRoomName)")
} else {
    print("无法检索到房间")
}

Output di atas eksekusi program adalah:

第一个房间名为客厅

Akses jenis opsional indeks

Jika indeks mungkin kembali null jenis nilai, seperti Swift di Kamus indeks kunci. Anda bisa menutup target berikutnya dalam tanda kurung setelah tanda tanya untuk menempatkan link ke subjek di bawah Nilai Kembali kosong:

var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0]++
testScores["Brian"]?[0] = 72
// the "Dave" array is now [91, 82, 84] and the "Bev" array is now [80, 94, 81]

Contoh di atas mendefinisikan array testScores berisi dua pasangan kunci-nilai, jenis kunci String dipetakan ke array integer.

Sampel ini panggilan dengan link opsional untuk "Dave" diatur ke elemen pertama dari array 91, elemen pertama +1 "Bev" array, dan kemudian mencoba untuk "Brian" Elemen pertama dari array diatur ke 72 .

Dua panggilan pertama berhasil, karena dua keberadaan kunci. Tapi kunci "Brian" dalam kamus tidak ada, sehingga panggilan ketiga gagal.


koneksi multi-link

Anda dapat rantai bersama-sama beberapa lapisan opsional dapat menggali dalam sifat model lebih bawah metode dan script indeks. Namun, opsional multi-chain dapat menambah nilai rasio opsional telah kembali lebih lapisan.

Jika Anda mencoba untuk mendapatkan melalui rantai nilai Int opsional, terlepas dari berapa banyak link layer selalu mengembalikan Int?. Demikian pula, jika Anda mencoba untuk mendapatkan melalui rantai opsional Int? Nilai, terlepas dari berapa banyak link layer selalu mengembalikan Int?.

contoh 1

Contoh berikut mencoba untuk mendapatkan sifat tinggal john dalam alamat jalan properti. Seperti yang digunakan disini, dua rantai opsional untuk menghubungi tinggal dan alamat atribut, keduanya adalah jenis opsional:

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()

if let johnsStreet = john.residence?.address?.street {
    print("John 的地址为 \(johnsStreet).")
} else {
    print("不能检索地址")
}

Output di atas eksekusi program adalah:

不能检索地址

contoh 2

Jika Anda memberi contoh ke alamat sebagai john.residence.address nilai dan menetapkan nilai untuk alamat jalan sebenarnya dari properti, Anda dapat rantai beberapa lapisan untuk mendapatkan ini opsional nilai atribut.

class Person {
   var residence: Residence?
}

class Residence {
    
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        get{
            return rooms[i]
        }
        set {
            rooms[i] = newValue
        }
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

class Room {
    let name: String
    init(name: String) { self.name = name }
}

class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}
let john = Person()
john.residence?[0] = Room(name: "浴室")

let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouse

if let firstRoomName = john.residence?[0].name {
    print("第一个房间是\(firstRoomName)")
} else {
    print("无法检索房间")
}

Contoh di atas output:

第一个房间是客厅

fungsi opsional dari nilai link kembali

Kami juga dapat memanggil metode mengembalikan nilai null oleh link opsional, dan Anda dapat melanjutkan pada link pengaturan alternatif.

contoh

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()

if john.residence?.printNumberOfRooms() != nil {
    print("指定了房间号)")
}  else {
    print("未指定房间号")
}

Output di atas eksekusi program adalah:

未指定房间号