class Dog {
var name: String?
var weight: Int
init(name: String, weight: Int) {
self.name = name
self.weight = weight
}
func sit() {
print("\(self.name)가 앉았습니다.")
}
func layDown() {
print("누웠습니다.")
}
}
class Human {
var dog: Dog?
}
만약에 인스턴스가 옵셔널타입이라면?
var choco: Dog? = Dog(name: "초코", weight: 15)
에러가 발생하고 choco뒤에 ?를 붙여야한다고 제안해준다
choco?.name
choco?.sit()
→ choco가 옵셔널 가능성이 있는경우 메서드를 “.”으로 접근할때 ?를 붙여야한다
Human인스턴스가 옵셔널로 선언이 되어있다면?
var human2: Human? = Human()
choco는 Dog?타입이기 때문에 dog의 타입과 일치해서 대입이 가능하다
human2?.dog = choco
human2?.dog?.name
human2도 옵셔널 dog도 옵셔널 name도 옵셔널이라서 전부다 ?를 붙여야할거같지만
→ 마지막건 옵셔널이어도 ?를 붙이지 않아도 괜찮다
💡 옵셔널 체이닝 (옵셔널 타입에 대해, 접근연산자 호출하는 방법)print(human2!.dog!.name) -> 옵셔널 타입으로 결과값이 나오기때문에 언래핑
print(human2!.dog!.name!) -> 강제언래핑한 경우
print(human2!.dog!.weight) -> weight는 옵셔널이 아니라 그냥 사용 가능
if let name = human2?.dog?.name {
print(name)
}
var defaultName = human2?.dog?.name ?? "멍탱구리"
print(defaultName)
class Cat {
// 함수가 있을수도 있고 없을수도 있다
var myMaster: (() -> Person?)?
init(aFunction: @escaping () -> Person?) {
self.myMaster = aFunction
}
}
class Person {
var name: String?
}
// return이 있을수도 있고 없을수도 있다
func meowmeow() -> Person? {
let person = Person()
person.name = "Jobs"
return person
}
인스턴스를 하나 만들어보면
var cat: Cat? = Cat(aFunction: meowmeow)
그리고 cat인스턴스안에 name이라는 키워드에 접근하려면
→ cat에 있는 mymaster이라는 함수에 접근해서 인스턴스를 반환한거에 name에 접근
var name = cat?.myMaster?()?.name
→ 소괄호 앞의 ?는 함수의 옵셔널 여부 뒤의 ?는 결과값의 옵셔널 여부
class Library1 {
var books: [String: Person]?
}
var person1 = Person()
person1.name = "Jobs"
var person2 = Person()
person2.name = "Musk"
var library = Library1()
library.books = ["Apple": person1, "Tesla": person2]
library.books?["Apple"]?.name
library.books?["Tesla"]?.name
var bori: Dog? = Dog(name: "보리", weight: 20)
// ⭐️ 앞의 타입이 옵셔널이라고 해서 메서드가 실행이 안되는 것은 아님
bori?.layDown()
bori?.sit()
bori = nil
// 타입의 값이 nil이면, 함수가 실행이 되지 않고 nil을 반
bori?.layDown()