Latest web development tutorials

Swift опционально цепь

Дополнительно цепь (Необязательно Chaining) является способ запросить и вызывает свойство, процессный подход и суб-сценарий предусматривает целевой запрос или может быть равен нулю.

Дополнительно цепь возвращает два значения:

  • Если цель имеет значение, то вызов завершается успешно, возвращаемое значение

  • Если цель равна нулю, то вызов будет возвращать ноль

Несколько запросов или вызовов могут быть соединены в цепь, если какой-либо узел равен нулю сбой приведет всю цепочку.


Дополнительно цепь альтернатива вынуждена Решимость

Путем добавления свойств, методов или дополнительного индекса значение сценария поставить знак вопроса (?), Вы можете определить дополнительную цепь.

Дополнительно цепь '?' Восклицательный знак (!) Чтобы заставить методы расширения, свойства, нижний индекс сценария необязательно цепь
? Необязательное значение, придаваемое на позже вызывая методы, свойства, индексного сценария ! Дополнительное значение, придаваемое на более поздних методов вызова, свойства, нижний индекс скрипт для расширения обязательных значений
Если дополнительный выход равен нулю более подробные сообщения об ошибках Когда опция расширения до нуля вынужден ошибки выполнения

Используйте восклицательного знака (!) Примеры опционального цепи

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

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

Выход выше выполнение программы:

fatal error: unexpectedly found nil while unwrapping an Optional value

Хотите использовать восклицательный знак (!) Для принудительного разбора этого лица места жительства значения numberOfRooms собственности недвижимости, он будет бросать ошибки во время выполнения, потому что тогда это значение не может быть использовано для проживания решена.

Используйте восклицательного знака (!) Примеры опционального цепи

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

Выход выше выполнение программы:

不能查看房间号

Поскольку эти попытки numberOfRooms операция может произойти сбой, необязательно цепь будет возвращать Int? Тип значение, или называется "Дополнительный Int". Когда резиденция была пуста, когда (пример), выберите Int будет пустым, так что не будет в случае numberOfRooms доступа.

Следует отметить, что даже неопциональные numberOfRooms Int (Int?) Когда это тоже верно. До тех пор пока запрос не является обязательным цепь с помощью конечной numberOfRooms всегда возвращают Int? Вместо Int.


Класс модели определяется как необязательного цепи

Вы можете использовать дополнительную цепь к свойствам нескольких вызовов, методов и индекса сценария. Это позволяет использовать сложные модели между ними, чтобы получить больше, лежащих в основе свойств, и проверить, можно ли получить такую ​​закладываемого имущества.

примеров

Модель определяет четыре класса, в том числе многовариантной цепи:

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

С помощью вызова метода опциональный цепи

Метод, чтобы вызвать альтернативные настройки, которые вы можете использовать дополнительную цепь и проверить вызов метода был успешным. Даже если этот метод не возвращает значение, вы все равно можете использовать дополнительную цепь для достижения этой цели.

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

Выход выше выполнение программы:

无法输出房间号

Используйте, если заявления для проверки успешного метода printNumberOfRooms вызова: Если вызов метода удается с помощью дополнительной цепи, printNumberOfRooms неявное возвращаемое значение будет Пустота, если не успешно, то возвращает ноль.


С помощью вызова сценария индекс опциональный цепи

Вы можете использовать дополнительную цепь, чтобы попытаться получить значение из стандартного сценария и рассмотрим следующий вызов нижний индекс сценария является успешным, однако, вы не можете установить дополнительный цепной индекс сценария.

Пример 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("无法检索到房间")
}

Выход выше выполнение программы:

无法检索到房间

Следующий стандартный сценарий вызывает дополнительный цепь непосредственно за circname.print знаком вопроса, следующий стандартный сценарий, потому что круглые скобки фронт circname.print опционально цепь пытается получить дополнительное значение.

Пример 2

Примеры случаев для создания Residence john.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("无法检索到房间")
}

Выход выше выполнение программы:

第一个房间名为客厅

Чтобы получить доступ к индексу с помощью дополнительного вызова линии связи

С помощью дополнительного вызова линии связи, мы можем использовать индекс для чтения или записи к дополнительному значению, и определяет вызов нижний индекс был успешным.

примеров

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

Выход выше выполнение программы:

第一个房间名为客厅

Доступ необязательный тип индекса

Если индекс может возвращать нулевой тип значения, такие как Swift в словаре ключа индекса. Вы можете закрыть следующую цель в скобках после знака вопроса поставить ссылку на эту тему под пустой Возвращаемое значение:

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]

Приведенный выше пример определяет массив testScores содержит две пары ключ-значение, ключ Строка типа отображается на целочисленный массив.

В этом примере вызовы с дополнительной ссылкой на "Dave" устанавливается на первый элемент массива 91, первый элемент +1 "Бев" массив, а затем попытаться "Brian" Первый элемент массива устанавливается в 72 ,

Первые два вызова успешно, потому что два ключевых присутствия. Но ключ "Брайан" в словаре не существует, поэтому третий вызов не удалось.


Подключение Многорычажная

Вы можете цепи вместе несколько слоев необязательно может быть копать в свойствах модели далее вниз методов и индекса сценария. Тем не менее, дополнительный мульти-цепь может добавить дополнительный коэффициент стоимости вернулся больше слоев.

Если вы пытаетесь получить с помощью дополнительной цепочки добавленной стоимости Int, независимо от того, сколько канального уровня всегда возвращает Int?. Точно так же, если вы пытаетесь получить с помощью дополнительной цепи Int? Value, независимо от того, сколько канального уровня всегда возвращает Int?.

Пример 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 johnsStreet = john.residence?.address?.street {
    print("John 的地址为 \(johnsStreet).")
} else {
    print("不能检索地址")
}

Выход выше выполнение программы:

不能检索地址

Пример 2

Если вы установите пример на адрес в качестве значения john.residence.address и задайте значение для фактического адрес собственности, вы можете цепи несколько слоев, чтобы получить это необязательные значения атрибутов.

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

В приведенном выше примере выход:

第一个房间是客厅

Дополнительная функция от значения обратной линии

Мы также можем вызвать метод возвращает нулевое значение необязательной ссылку, и вы можете продолжать по ссылке альтернативной настройки.

примеров

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

Выход выше выполнение программы:

未指定房间号