SWIFT公式ドキュメント:Optional Chainingについて

19663 ワード

傍観者


不思議なことに、客席が混乱しすぎて、正式な書類を見て整理しました.
光学スクリーニングとは、光学のプロパティ、メソッド、サブスクリプトを組み込むときに使用される方法です.所望の値がnilの場合、nilが返されます(所望の値がnilの場合、nilが返されます).複数のクエリーはチェーンのように接続され、そのうちの1つがnilの場合、nilが返されます.

強制バックフラッシュとの比較


Property、メソッド、サブスクリプトの外部値をインポートした後?使用します.これは強制的に吹いたのです!と...の差は多くない.(!席に?と書いてあります)
しかし、重要な違いは、傍観者がnilの場合、強制的に包装をキャンセルすると、運転中にエラーが発生することです.
つまり、ゆったりしたスニーカーで脱ぐと、優雅にゼロに戻り、失敗します.

オフセット量は常にオフセット値を返します


偏光フィルタリングに失敗するとnilが返されるため、偏光フィルタリングは常に偏光値を返します.
→外来値のProperty、Methodなど、外来値でなくても外来値を返します
例)アクセスがIntのPropertyに戻った場合、Intを使用しますか?リターンマッチ

最初の単純な例

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()
現在、外来型と発表されている住宅は無価状態だ.
//방법1) 강제 언래핑 !
let roomCount = john.residence!.numberOfRooms 
print(roomCount) //residence가 nil이라면 런타임 에러

//방법2) 옵셔널 체이닝 ?
if let roomCount = john.residence?.numberOfRooms {
    print(roomCount)
} else {
    print("값 가져오기 실패")
}

きょうせいふきつけ


:強制的に部屋代を差し引いて、専門のroomCount値を持ってきます
→強引に剥がす、価値がなければ運行時に発生する大災害

傍観者


:居留料があれば、プロのroomCount値を取って、なければnilを返す→値がなければ優雅に失敗して、大丈夫です.
:nilが返す可能性があるので、常に外来値を返します.

返されたオフセット値をオフセットバインドとして定数に割り当てます。


しかしなぜprint(roomCount)は外来値ではないのでしょうか.
フィルタを終了して値を正常に返すと、roomCountに割り当てられ、バインドを終了する形で終了します.
従って、光学フィルタリングに成功した場合→バインディングにも成功し、最終的に得られるのは光学値の値ではない.john.residence = Residence()居住地構成に値を割り当て、再配置を試みたときに正常に値を返します.

2つ目の少し複雑な例


光学フィルタで値を取得し、値を割り当てることができます.
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 let buildingNumber = buildingNumber, let street = street {
            return "\(buildingNumber) \(street)"
        } else if buildingName != nil {
            return buildingName
        } else {
            return nil
        }
    }
}
間違えて絵を描いた
  • PersonクラスのインスタンスJohn,AddressクラスのインスタンスsomeAddressの場合
  • johnのaddressは1)傍観者スコアに割り当てることができず,2)傍観者スコアを導入することができない.
    理由は今のjohn住宅がゼロなので.
    johnのaddressを取り出すには、取り出す交差点で住宅の段階を通る必要がありますが、nilなので取り出すことができません.
    let john = Person()
    let someAddress = Address()
    someAddress.buildingNumber = "29"
    someAddress.street = "사과로"
    john.residence?.address = someAddress //john의 주소를 할당해주기 실패
    if let johnsAddress = john.residence?.address {
        print("주소: \(johnsAddress)")
    } else {
        print("주소 가져오기 실패")
    }
    //주소 가져오기 실패
  • PersonクラスのインスタンスJohnとResidenceクラスのインスタンスJohnsHouseの場合
  • johnの住宅にjohnshouseを割り当てた後、room propertyを追加します.
    光学ギャップで番号間を取り出すことができます.
    let john = Person()
    let johnsHouse = Residence()
    johnsHouse.rooms.append(Room(name: "거실"))
    johnsHouse.rooms.append(Room(name: "거실"))
    john.residence = johnsHouse
    if let roomCount = john.residence?.numberOfRooms {
        print("방 개수: \(roomCount)")
    } else {
        print("방 개수 가져오기 실패")
    }
  • PersonクラスのインスタンスJohn,ResidenceクラスのインスタンスJohn,
  • johnのstreetは、AddressクラスのインスタンスjohnsAddressの場合にのみポップアップできます.
    let john = Person()
    
    let johnsHouse = Residence()
    johnsHouse.rooms.append(Room(name: "거실"))
    johnsHouse.rooms.append(Room(name: "거실"))
    john.residence = johnsHouse
    
    let johnsAddress = Address()
    johnsAddress.buildingName = "사과빌딩"
    johnsAddress.street = "사과로"
    john.residence?.address = johnsAddress
    if let johnsStreetAddress = john.residence?.address?.street {
        print("도로명주소: \(johnsStreetAddress)")
    } else {
        print("도로명주소 가져오기 실패")
    }
    上のコードは実は下のコードのように重なるロケータを使うべきですが、面倒なのでロケータが発生します.
    if let johnsHouse = john.residence {
        if let johnsAddress = johnsHouse.address {
            if let johnsStreet = johnsAddress.street {
                print("도로명주소: \(johnsStreet)")
            } else {
                print("도로명주소 가져오기 실패")
            }
        }
    }