Latest web development tutorials

Swift optional Kette

Optional Kette (Optional Chaining) ist ein ein Weg, um zu verlangen, und ruft die Eigenschaft, die Prozess-Ansatz und Sub-Skript für die Zielanforderung aufruft oder gleich null.

Optional Kette gibt zwei Werte:

  • Wenn das Ziel einen Wert hat, ist der Aufruf erfolgreich, den Rückgabewert

  • Wenn das Ziel ist gleich Null, wird der Anruf Fehlanzeige

Mehrere Anfragen oder Anrufe können in eine Kette verbunden werden, wenn jeder Knoten Null Ausfall ist die gesamte Kette verursachen.


Optional Kette Alternative gezwungen Entschlossenheit

Durch Anhängen Eigenschaften, Methoden oder optionaler Wert Index Skript ein Fragezeichen setzen (?), Können Sie eine optionale Kette definieren.

Optional Kette '?' Ausrufezeichen (!) Zu erzwingen Erweiterung Methoden, Eigenschaften Index Skript optional Kette
? Ein optionaler Wert, auf den späteren Aufrufen von Methoden gelegt, Eigenschaften, Index-Skript ! Auf den späteren Aufruf von Methoden gelegt Optional Wert, Eigenschaften, Index Skript verbindlichen Werte zu erweitern
Wenn die optionale Ausgabe ist gleich Null freundlicher Fehlermeldungen Wenn die optionale Erweiterung auf Null gezwungen Ausführungsfehler

Verwenden Sie das Ausrufezeichen (!) Beispiele für optionalen Ketten

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

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

Die obige Programmausführung Ausgabe ist:

fatal error: unexpectedly found nil while unwrapping an Optional value

Möchten Sie ein Ausrufezeichen zu verwenden (!), Um das Parsen dieser Person Residenz Eigenschaft numberOfRooms Eigenschaft Wert zu erzwingen, wird es einen Laufzeitfehler zu werfen, weil dann kein Wert ist, kann gelöst für den Aufenthalt verwendet werden.

Verwenden Sie das Ausrufezeichen (!) Beispiele für optionalen Ketten

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("不能查看房间号")
}

Die obige Programmausführung Ausgabe ist:

不能查看房间号

Da diese Versuche numberOfRooms Operation fehlschlagen kann, wird optional Kette zurückgeben Int? Typ-Wert oder "Optional Int" genannt. Wenn der Aufenthalt war leer, als (das Beispiel), wählen Sie Int leer sein wird, so wird es der Fall der Zugang numberOfRooms nicht sein.

Es sollte beachtet werden, dass auch nicht-optionalen numberOfRooms Int (Int?) Wenn dies auch der Fall ist. Solange die Anforderung mittels einer abschließenden numberOfRooms optional Kette ist immer Int zurückgeben? Stattdessen Int.


Modellklasse wird als optionale Kette definiert

Sie können eine optionale Kette Multi-Call-Eigenschaften, Methoden und Index-Skript verwenden. Auf diese Weise können Sie komplexe Modelle zwischen ihnen zu nutzen, um mehr zugrunde liegenden Eigenschaften zu erhalten, und prüfen Sie, ob Sie solche zugrunde liegenden Immobilie erhalten.

Beispiele

Modell definiert vier Klassen, einschließlich multioptionalem Kette:

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
        }
    }
}

Mit den optionalen Kettenmethodenaufrufe

Methode zum Aufrufen der alternativen Einstellungen Sie können eine optionale Kette verwenden und überprüfen der Methodenaufruf erfolgreich war. Auch wenn diese Methode keinen Wert zurückgibt, können Sie immer noch eine optionale Kette verwenden diesen Zweck zu erreichen.

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("无法输出房间号")
}

Die obige Programmausführung Ausgabe ist:

无法输出房间号

Zu verwenden, wenn Aussagen, ob ein erfolgreicher Aufruf printNumberOfRooms Methode zu überprüfen: Wenn der Aufruf der Methode durch eine optionale Kette erfolgreich ist, wird printNumberOfRooms impliziten Rückgabewert der Leere, wenn nicht erfolgreich, es null zurückgibt.


Mit dem optionalen Kettenruf Index Skript

Sie können eine optionale Kette, um zu versuchen, um den Wert aus dem Standard-Skript zu erhalten und der nächste Aufruf Index Skript erfolgreich ist, jedoch zu prüfen, können Sie nicht einen optionalen Kettenindex Skript gesetzt.

Beispiel 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("无法检索到房间")
}

Die obige Programmausführung Ausgabe ist:

无法检索到房间

Der nächste Standard-Script die optionale Kette direkt hinter circname.print Fragezeichen nennt, ist der nächste Standard-Script Klammern vorne, weil circname.print optional Kette versucht, den optionalen Wert zu erhalten.

Beispiel 2

Beispiele für Fälle, eine Residenz john.residence zu schaffen, und eine oder mehrere Instanzen seiner Räume Zimmer Array, dann können Sie die optionale Kette verwenden Räume im Array-Instanz von Residence Index Skript zu erhalten:

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("无法检索到房间")
}

Die obige Programmausführung Ausgabe ist:

第一个房间名为客厅

Um den Index über optionale Link Anruf zugreifen

Mit dem optionalen Link Anruf, können wir den Index verwenden, um auf einen beliebigen Wert gelesen oder geschrieben werden, und bestimmt der Index Aufruf erfolgreich war.

Beispiele

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("无法检索到房间")
}

Die obige Programmausführung Ausgabe ist:

第一个房间名为客厅

Zugang optional Indextyp

Wenn der Index null Werttyp zurückgeben kann, wie Swift im Wörterbuch des Schlüsselindex. Sie können das nächste Ziel in Klammern hinter dem Fragezeichen schließen einen Link zu diesem Thema unter leeren Rückgabewert zu setzen:

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]

Das obige Beispiel definiert ein testScores Array enthält zwei Schlüssel-Wert-Paare wird der Typ String Schlüssel zu einem Integer-Array abgebildet.

Dieses Beispiel ruft mit einem optionalen Link zu "Dave" ist mit dem ersten Element des Arrays 91, das erste Element +1 "Bev" Array gesetzt, und versuchen Sie dann zu "Brian" Das erste Element des Arrays ist auf 72 .

Die ersten beiden Anrufe sind erfolgreich, weil die beiden Schlüssel Präsenz. Aber der Schlüssel "Brian" im Wörterbuch nicht existiert, so dass der dritte Anruf fehlgeschlagen.


Multi-Link-Verbindung

Sie können Kette zusammen mehrere Schichten gegebenenfalls weiter im Modell Graben Eigenschaften werden unten die Methoden und Index-Skript. Jedoch ist eine optionale Multikette kann optional Wertverhältnis hinzufügen hat mehr Schichten zurückgeführt.

Wenn Sie versuchen, über den optionalen Int-Wertschöpfungskette zu erhalten, unabhängig davon, wie viele Verbindungsschicht Int immer wieder?. Und falls Sie versuchen, über die optionale Kette zu bekommen Int? Wert, unabhängig davon, wie viele Verbindungsschicht immer wieder Int?.

Beispiel 1

Im folgenden Beispiel wird versucht, Johns Residenz Eigenschaften in der Straße Adresse der Immobilie zu erhalten. Wie hier verwendet, sind die zwei optionalen Ketten zu kontaktieren Wohnsitz und Adresse Attribute, die beide optional Typ:

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("不能检索地址")
}

Die obige Programmausführung Ausgabe ist:

不能检索地址

Beispiel 2

Wenn Sie ein Beispiel für die Adresse als Wert john.residence.address gesetzt und einen Wert für die tatsächliche Adresse der Immobilie einstellen, können Sie Kette mehrere Schichten dieses optionale Attributwerte zu erhalten.

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("无法检索房间")
}

Das obige Beispiel Ausgabe lautet:

第一个房间是客厅

Optionale Funktion des Wertes des Rückverbindung

Wir können auch die Methode aufrufen, einen Nullwert durch einen optionalen Link zurück, und Sie können auf die alternative Einstellungen Link weiter.

Beispiele

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("未指定房间号")
}

Die obige Programmausführung Ausgabe ist:

未指定房间号