Latest web development tutorials

cadeia opcional Swift

cadeia opcional (opcional encadeamento) é uma é uma forma de solicitar e chama a propriedade, a abordagem processo e sub-script chama para a solicitação de destino ou pode ser nulo.

cadeia opcional retorna dois valores:

  • Se o alvo tem um valor, a chamada tiver êxito, o valor de retorno

  • Se o alvo é zero, a chamada retornará nil

Várias solicitações ou chamadas podem ser ligados em uma cadeia, se qualquer nó é o fracasso nil fará com que toda a cadeia.


alternativa cadeia opcional determinação forçado

Por propriedades anexas, métodos ou script de índice de valor opcional colocar um ponto de interrogação (?), Você pode definir uma cadeia opcional.

cadeia opcional '?' ponto de exclamação (!) Para forçar métodos de expansão, propriedades, cadeia opcional roteiro subscrito
? Um valor opcional colocado no métodos, propriedades, roteiro subscrito depois de chamar ! Valor opcional colocado sobre os métodos de chamada posteriores, propriedades, roteiro subscrito para expandir valores obrigatórios
Quando a saída opcional é nulo mensagens de erro mais amigáveis Quando a expansão opcional a zero forçado erro de execução

Use o ponto de exclamação (!) Exemplos de cadeia opcional

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

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

A saída de execução de programa acima é:

fatal error: unexpectedly found nil while unwrapping an Optional value

Quer usar um ponto de exclamação (!) Para forçar a análise desse valor numberOfRooms propriedade pessoa residência, ele lançará um erro de execução, porque então não há nenhum valor pode ser usado para a residência resolvido.

Use o ponto de exclamação (!) Exemplos de cadeia opcional

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

A saída de execução de programa acima é:

不能查看房间号

Porque essas tentativas numberOfRooms operação pode falhar, cadeia opcional voltará Int? Valor Tipo, ou chamado de "Opcional Int". Quando a residência estava vazia quando (o exemplo), selecione Int estará vazio, de modo que não será o caso de numberOfRooms de acesso.

Deve-se notar que mesmo numberOfRooms não opcionais Int (Int?) Quando isso também é verdadeiro. Enquanto o pedido de cadeia facultativo é por meio de um numberOfRooms finais sempre voltar Int? Em vez Int.


classe de modelo é definido como cadeia opcional

Você pode usar uma cadeia opcional para propriedades multi-chamada, métodos e roteiro índice. Isso permite que você use modelos complexos entre eles para conseguir mais propriedades subjacentes, e verificar se é possível obter tal propriedade subjacente.

Exemplos

Modelo define quatro classes, incluindo cadeia de multi-opcional:

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

Com as chamadas de método de cadeia opcional

Método para invocar as configurações alternativas que você pode usar uma cadeia opcional e verifique a chamada de método foi bem-sucedida. Mesmo que esse método não retorna um valor, você ainda pode usar uma cadeia opcional para alcançar este objectivo.

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

A saída de execução de programa acima é:

无法输出房间号

Use if para verificar se um método printNumberOfRooms chamada bem-sucedida: Se a chamada do método for bem-sucedido através de uma cadeia opcional, printNumberOfRooms valor de retorno implícita será the Void, se não for bem-sucedido, ele retorna nulo.


Usando o script chamada subscrito cadeia opcional

Você pode usar uma cadeia opcional para tentar obter o valor a partir do script padrão e examinar o próximo script chamada subscrito for bem sucedida, no entanto, não é possível definir um script índice em cadeia opcional.

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

A saída de execução de programa acima é:

无法检索到房间

O próximo script padrão chama a cadeia opcional diretamente atrás do ponto de interrogação circname.print, o próximo script padrão parênteses frente, porque circname.print cadeia opcional tentando obter o valor opcional.

exemplo 2

Exemplos de instâncias para criar um john.residence Residence, e uma ou mais instâncias de sua matriz quartos quarto, então você pode usar a cadeia opcional para obter quartos na instância de matriz por Residence subscrito script:

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

A saída de execução de programa acima é:

第一个房间名为客厅

Para acessar o índice através de chamada ligação opcional

Com a chamada ligação opcional, podemos usar o índice a ser lido ou escrito um valor opcional, e determina o chamado índice foi bem sucedida.

Exemplos

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

A saída de execução de programa acima é:

第一个房间名为客厅

Acesso opcional tipo de índice

Se o índice pode retornar tipo de valor nulo, como Swift no Dicionário do índice de chave. Você pode fechar o próximo alvo entre parênteses após o ponto de interrogação para colocar um link para o assunto em Valor de retorno vazio:

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]

O exemplo acima define uma matriz testScores contém dois pares de valores-chave, a chave tipo String é mapeado para uma matriz de inteiros.

Este exemplo chama com um link opcional para "Dave" é definido para o primeiro elemento da matriz 91, o primeiro elemento de um array "Bev", e depois tentar "Brian" O primeiro elemento da matriz é definido para 72 .

As duas primeiras chamadas são bem sucedidos, porque os dois presença chave. Mas a chave "Brian" no dicionário não existe, portanto, a terceira chamada falhou.


conexão multi-link

Você pode encadear múltiplas camadas, opcionalmente, pode estar cavando dentro das Propriedades modelo mais abaixo os métodos e roteiro índice. No entanto, um multi-cadeia opcional pode adicionar rácio valor opcional voltou mais camadas.

Se você tentar obter através da cadeia de valor Int opcional, independentemente de quantos camada de enlace sempre retorna Int?. Da mesma forma, se você tentar obter através da cadeia opcional Int? Valor, independentemente de quantos camada de enlace sempre retorna Int?.

exemplo 1

O exemplo a seguir tenta obter as propriedades de residência de João no endereço da propriedade. Tal como aqui utilizado, o dois de cadeia facultativo para contactar atributos de residência e de endereços, ambos são do tipo opcional:

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

A saída de execução de programa acima é:

不能检索地址

exemplo 2

Se você definir um exemplo para o endereço como um john.residence.address valor e definir um valor para o endereço real da propriedade, você pode cadeia de múltiplas camadas para obter estes valores de atributos opcionais.

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

O exemplo acima saída é:

第一个房间是客厅

Opcional função do valor da ligação de retorno

Também pode chamar o método retorna um valor nulo por um link opcional, e você pode continuar no link configurações alternativa.

Exemplos

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

A saída de execução de programa acima é:

未指定房间号