스위프트 옵션 체인
선택적 쇄 (선택 체이닝) 프로세스 방식과 서브 스크립트 대상 요청 호출 또는 전무 수 있고, A가 요청하는 방법 및 속성을 호출한다.
옵션 체인은 두 값을 반환합니다 :
타겟 값을 갖는 경우, 호출이 리턴 값 성공
대상이 전무 경우, 호출이 전무를 반환합니다
모든 노드가 전체 체인의 원인이됩니다 전무 실패 인 경우 여러 요청이나 호출, 체인으로 연결할 수 있습니다.
옵션 체인 대안 강제 해결
추가 속성, 메서드 또는 물음표 (?)를 넣어 옵션 값 인덱스 스크립트에 의해, 당신은 선택 사양 체인을 정의 할 수 있습니다.
옵션 체인 '?' | 느낌표 (!) 확장 메서드, 속성을 강제하려면, 첨자 스크립트 옵션 체인 |
? 나중에 호출 메서드, 속성, 첨자 스크립트에 배치하는 옵션 값 | 나중에 호출 방법에 배치! 옵션 값, 속성, 첨자 스크립트는 필수 값을 확장 |
선택 사양 출력은 더 쉬운 오류 메시지 전무 경우 | 때 nil을 강제 실행 오류에 대한 옵션 확장 |
느낌표 (!)를 사용 옵션 체인의 예를
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 작업이 실패 할 수 있기 때문에, 옵션 체인 유형 값 지능? 돌아가거나 "옵션 지능"라는 것입니다. 거주지가 비어있을 때 때 (예), 지능이 비어있을 것입니다 선택, 그래서 액세스 numberOfRooms의 경우가되지 않습니다.
그것은 주목해야 심지어 비 선택 numberOfRooms 지능 (INT?)이도 마찬가지입니다. 한 요청이 최종 numberOfRooms에 의해 선택 체인이기 때문에 항상 대신? 지능을 지능을 반환합니다.
모델 클래스는 선택 사양 체인으로 정의된다
당신은 다중 통화 속성, 메서드 및 인덱스 스크립트 옵션 체인을 사용할 수 있습니다. 이것은 당신이 더 기본 속성을 얻기 위해 그들 사이에 복잡한 모델을 사용하고 같은 기본 속성을 얻을 수 있는지 여부를 확인할 수 있습니다.
예
모델은 멀티 옵션 체인 등 4 개 클래스를 정의한다 :
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
인스턴스의 예로는 레지던스 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("无法检索到房间") }
위의 프로그램 실행 출력은 다음과 같습니다
第一个房间名为客厅
인덱스의 액세스 옵션 유형
인덱스는 키 인덱스의 사전에서 스위프트에 null 값 유형을 반환 할 수 있습니다합니다. 당신은 빈 반환 값에 따라 대상에 대한 링크를 넣어 물음표 후 괄호 안에 다음 목표를 닫을 수 있습니다 :
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]
위의 예는 String 형의 키는 정수 배열에 매핑하는 testScores 어레이는 두 개의 키 - 값 쌍을 포함 정의합니다.
이 샘플은 배열 (91), 첫 번째 요소 일 "베브"배열의 첫 번째 요소로 설정 옵션 링크 "데이브"로 호출 한 다음 72로 설정되어 "브라이언"배열의 첫 번째 요소에 시도 .
처음 두 호출이 때문에 두 가지 핵심 존재, 성공. 세 번째 호출이 실패 있도록하지만 사전에 키 "브라이언은"존재하지 않습니다.
멀티 - 링크 접속
당신은 체인 함께 여러 층을 선택적 방법과 인덱스 스크립트 더 아래 모델 속성 내에서 파고 될 수 있습니다. 그러나, 옵션 값의 비율을 추가 할 수있는 옵션 멀티 체인 이상의 층을 반환했습니다.
에 관계없이 항상 int를 돌려 얼마나 많은 링크 층, 옵션 지능 가치 사슬을 통과하려고하면?. 마찬가지로, 당신이 상관없이 항상 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("无法检索房间") }
위 예제의 출력은 다음과 같습니다
第一个房间是客厅
리턴 링크의 값 옵션 기능
우리는 또한이 방법은 임의의 링크로 null 값을 반환 호출 할 수 있습니다, 당신은 다른 설정 링크를 계속할 수 있습니다.
예
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("未指定房间号") }
위의 프로그램 실행 출력은 다음과 같습니다
未指定房间号