Latest web development tutorials

chaîne optionnelle Swift

Chaîne en option (option Chaining) est un est un moyen de demander et demande la propriété, l'approche processus et sous-script appelle pour la demande de cible ou pourrait être nul.

chaîne en option retourne deux valeurs:

  • Si la cible a une valeur, l'appel réussit, la valeur de retour

  • Si la cible est nul, l'appel retournera nil

les demandes ou les appels multiples peuvent être reliés dans une chaîne, si un nœud est nul échec provoquera l'ensemble de la chaîne.


détermination forcée en option alternative de la chaîne

Par propriétés annexées, méthodes ou option script indice de valeur mettre un point d'interrogation (?), Vous pouvez définir une chaîne en option.

chaîne en option '?' Point d'exclamation (!) Pour forcer les méthodes d'expansion, les propriétés, le script indice chaîne optionnelle
? Une valeur optionnelle placée sur la remise ultérieure des méthodes, propriétés, script indice ! Valeur optionnelle placée sur les méthodes d'appel plus tard, les propriétés, le script de l'indice d'étendre les valeurs obligatoires
Lorsque la sortie en option est nul messages d'erreur plus respectueux Lorsque l'extension en option à zéro erreur d'exécution forcée

Utilisez le point d'exclamation (!) Exemples de chaîne optionnelle

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

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

La sortie de l'exécution du programme ci-dessus est la suivante:

fatal error: unexpectedly found nil while unwrapping an Optional value

Vous souhaitez utiliser un point d'exclamation (!) Pour forcer l'analyse de cette valeur de la propriété numberOfRooms de propriété de la résidence de la personne, il va lancer une erreur d'exécution, car alors il n'y a aucune valeur ne peut être utilisé pour la résidence résolu.

Utilisez le point d'exclamation (!) Exemples de chaîne optionnelle

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

La sortie de l'exécution du programme ci-dessus est la suivante:

不能查看房间号

Parce que le fonctionnement de ces tentatives peut échouer, la chaîne optionnelle retourne Int? Valeur de type, ou appelé "option Int". Lorsque la résidence était vide quand (l'exemple), sélectionnez Int sera vide, donc il ne sera pas le cas d'accès numberOfRooms.

Il convient de noter que même numberOfRooms non-option Int (Int?) Lorsque cela est également vrai. Tant que la demande est la chaîne en option au moyen d'une finale numberOfRooms toujours revenir Int? Au lieu Int.


classe de modèle est définie comme la chaîne optionnelle

Vous pouvez utiliser une chaîne optionnelle propriétés multi-appels, les méthodes et le script d'index. Cela vous permet d'utiliser des modèles complexes entre eux pour obtenir plus de propriétés sous-jacentes, et vérifiez si vous pouvez obtenir une telle propriété sous-jacente.

Exemples

Modèle définit quatre classes, y compris la chaîne multi-option:

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

Avec la méthode chaîne facultative appels

Méthode d'invoquer les paramètres alternatifs, vous pouvez utiliser une chaîne optionnelle et vérifier l'appel de méthode a réussi. Même si cette méthode ne retourne pas de valeur, vous pouvez toujours utiliser une chaîne en option pour atteindre cet objectif.

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

La sortie de l'exécution du programme ci-dessus est la suivante:

无法输出房间号

Utilisez if pour vérifier si la réussite d'une méthode printNumberOfRooms d'appel: Si l'appel de méthode réussit par une chaîne optionnelle, printNumberOfRooms valeur de rendement implicite sera le vide, il ne réussit pas, il renvoie nil.


Utilisation du script d'appel de l'indice de la chaîne optionnelle

Vous pouvez utiliser une chaîne optionnelle pour essayer d'obtenir la valeur du script standard et examiner le script suivant appel est réussie indice, cependant, vous ne pouvez pas définir un script d'index de la chaîne en option.

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

La sortie de l'exécution du programme ci-dessus est la suivante:

无法检索到房间

Le script suivant la norme appelle la chaîne optionnelle directement derrière circname.print d'interrogation, le prochain écriture standard parenthèses avant parce circname.print chaîne optionnelle essayant d'obtenir la valeur en option.

exemple 2

Des exemples de cas pour créer un john.residence de résidence, et une ou plusieurs instances de son réseau des chambres de chambre, vous pouvez utiliser la chaîne en option pour obtenir les chambres de l'instance de tableau par le script Residence:

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

La sortie de l'exécution du programme ci-dessus est la suivante:

第一个房间名为客厅

Pour accéder à l'index via une liaison facultative appel

Avec le lien appel en option, nous pouvons utiliser l'index pour être lu ou écrit à une valeur facultative, et détermine l'appel de l'indice a réussi.

Exemples

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

La sortie de l'exécution du programme ci-dessus est la suivante:

第一个房间名为客厅

Accès optionnel type d'index

Si l'indice peut retourner le type de valeur nulle, tels que Swift dans le Dictionnaire de l'index de clé. Vous pouvez fermer la prochaine cible entre parenthèses après le point d'interrogation pour mettre un lien vers le sujet sous vide Valeur de retour:

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]

L'exemple ci-dessus définit un réseau testScores contient deux paires clé-valeur, la clé de type String est mappé à un tableau d'entiers.

Cet exemple appelle avec un lien optionnel pour "Dave" est réglé sur le premier élément du tableau 91, le premier élément +1 "Bev" array, puis essayer de "Brian" Le premier élément du tableau est réglé sur 72 .

Les deux premiers appels sont couronnées de succès, parce que les deux présence clé. Mais la clé "Brian" dans le dictionnaire n'existe pas, de sorte que le troisième appel a échoué.


connexion multi-link

Vous pouvez enchaîner plusieurs couches peuvent éventuellement être creuser dans les propriétés du modèle plus bas les méthodes et le script d'index. Cependant, un multi-chaîne optionnelle peut ajouter le rapport option de valeur est revenue plusieurs couches.

Si vous essayez de passer à travers la chaîne de valeur Int option, indépendamment du nombre de couche lien renvoie toujours Int?. De même, si vous essayez de passer à travers la chaîne optionnelle Value, Int? Indépendamment du nombre de couche lien renvoie toujours Int?.

exemple 1

L'exemple suivant tente d'obtenir les propriétés de résidence de John dans l'adresse de la rue de la propriété. Tel qu'utilisé ici, les deux chaînes en option Contact résidence et adresse attributs, les deux sont de type option:

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

La sortie de l'exécution du programme ci-dessus est la suivante:

不能检索地址

exemple 2

Si vous définissez un exemple à l'adresse comme un john.residence.address de valeur et définissez une valeur pour l'adresse de la rue réelle de la propriété, vous pouvez enchaîner plusieurs couches pour obtenir ces valeurs d'attributs facultatifs.

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

L'exemple ci-dessus sortie est:

第一个房间是客厅

Fonction optionnelle de la valeur de la liaison de retour

Nous pouvons également appeler la méthode renvoie une valeur nulle par une liaison facultative, et vous pouvez continuer sur le lien Paramètres de remplacement.

Exemples

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

La sortie de l'exécution du programme ci-dessus est la suivante:

未指定房间号