2019년 1월 16일 수요일

Optional Chaining

Swift Programming Language Guide: Optional Chaining ,  코드부분


/* Optional Chaining */

// Optional Chaining as an Alternative to Forced Unwrapping

class Person {
   var residence: Residence?
}

class Residence {
   var numberOfRooms = 1
}

let john = Person()
let roomCount = john.residence?.numberOfRooms

if let roomCount = john.residence?.numberOfRooms {
   print("John's residence has \(roomCount) room(s).")
} else {
   print("Unable to retrieve the number of rooms.")
}

john.residence = Residence()
if let roomCount = john.residence?.numberOfRooms {
   print("John's residence has \(roomCount) room(s).")
} else {
   print("Unable to retrieve the number of rooms.")
}

// Defining Model Classes for Optional Chaining

class Person {
   var reidence: 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("The number of rooms is \(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
       }
   }
}

// Accessing Properties Through Optional Chaining

let john = Person()
if let roomCount = john.reidence?.numberOfRooms {
   print("John's residence has \(roomCount) room(s)")
} else {
   print("Unable to retrieve the number of rooms.")
}

let someAddress = Address()
someAddress.buildingNumber = "29"
someAddress.street = "Acacica Road"
john.reidence?.address = someAddress

func creatAddress() -> Address {
   print("Function was called.")
   
   let someAddress = Address()
   someAddress.buildingNumber = "29"
   someAddress.street = "Acacia Road"
   
   return someAddress
}

john.reidence?.address = creatAddress()

// Calling Methods Through Optional Chaining

if john.reidence?.printNumberOfRooms() != nil {
   print("It aws possible to print the number of rooms.")
} else {
   print("It as not possible to print the number of rooms")
}

if (john.reidence?.address = someAddress) != nil {
   print("It was possible to set the address.")
} else {
   print("It was not possible to set the address.")
}

// Accessing Subscripts Through Optional Chaining


if let firstRoomName = john.reidence?[0].name {
   print("The first room name is \(firstRoomName).")
} else {
   print("Unable to retrieve the first room name.")
}
john.reidence?[0] = Room(name: "BathRoom")

let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "Living Room"))
johnsHouse.rooms.append(Room(name: "Kitchen"))
john.reidence = johnsHouse

if let firstRoomName = john.reidence?[0].name {
   print("The first room name is \(firstRoomName).")
} else {
   print("Unable to retrieve the first room name.")
}

// Accessing Subscripts of Optional Type

var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0] += 1
testScores["Brain"]?[0] = 72

// Linking Multiple Levels of Chaining

if let johnsStreet = john.reidence?.address?.street {
   print("John's street name is \(johnsStreet)")
} else {
   print("Unable to retrieve the address.")
}

let johnAddress = Address()
johnAddress.buildingName = "The Larches"
johnAddress.street = "Laurel Street"
john.reidence?.address = johnAddress
if let johnStreet = john.reidence?.address?.street {
   print("John's street name is \(johnStreet)")
} else {
   print("Unable to retrieve the address.")
}

// Chaining on Methods with Optional Return Values.

if let buildingIdentifier = john.reidence?.address?.buildingIdentifier() {
   print("John's building identifier is \(buildingIdentifier)")
}

if let beginsWithThe = john.reidence?.address?.buildingIdentifier()?.hasPrefix("The") {
   if beginsWithThe {
       print("John's building identifier begins with \"The\".")
   } else {
       print("John's building identifier does not begin with \"The\".")
   }
}