개발_iOS/스위프트

[Swift] 100 Days of Swift - Day 12 정리

sophie_l 2022. 3. 31. 01:07

https://www.hackingwithswift.com/100/12

 

Day 12 – 100 Days of Swift

Follow the 100 Days of Swift and learn to build apps for free.

www.hackingwithswift.com

1. 옵셔널: 값이 없을 수도 있는 경우에 사용하며, 모든 타입에 대하여 만들 수 있다. 옵셔널은 옵셔널이 아닌 값과 함께 연산해줄 수 없다. 같은 타입이 아니기 때문

var name: String? = nil

name = "Sophie"

⭐️ 2. "optional binding" (unwrapping optionals): 옵셔널은 언래핑하기 전에는 사용할 수 없다. 언래핑 방법에는 if let과 guard let이 있다.

var name: String? = nil

if let unwrapped = name {
	print("Hello, \(unwrapped).")
} else {
	print("no name")
}

func greet(_ name: String?) {
	guard let unwrapped = name else {
		print("you didn't provide a name")
		return
	}
	print("Hello, \(unwrapped).")
}

guard let의 경우 nil을 찾으면 nil이 사용된 function, loop, condition 등을 탈출하게 해준다. else도 빼먹지 말것

 

3. force unwrapping: 강제로 언래핑해주는 것. nil일 경우 코드가 crash하므로 nil이 아닌 게 확실할 때만 써줄 것. 느낌표를 사용한다.

let str = "5"

let num = Int(str)!

⭐️ 4. implicitly unwrapped optionals: 옵셔널을 non optional처럼 언래핑하지 않고 써줄 수 있다. 그러나 nil일 경우 역시 코드가 충돌한다. 타입 이름 다음에 !를 써주면 되고, implicitly unwrapped optional을 사용하면 if let, guard let을 쓰지 않는다.

어떤 경우에 쓰는가? 처음에는 nil로 시작하지만 사용하기 전에 값을 할당받는 경우에 써준다. 그렇지 않은 경우에는 일반적인 옵셔널을 사용하는 게 더 나음.

let age: Int! = nil

⭐️ 5. nil coalescing: 옵셔널을 언래핑하면서 값이 있는 경우엔 해당 값을, nil일 경우 디폴트 값을 반환해준다. 어느 경우라도 결괏값이 옵셔널이 되지 않는다. ??로 표시해준다.

func username(for id: Int) -> String? {
	if id == 1 {
		return "Taylor Swift"
	} else {
		return nil
	}
}

let user = username(for: 15) ?? "Anonymous"

6. optional chaining: 옵셔널 체이닝은 a.b.c 형식으로 접근해야 하는 경우에 b가 옵셔널이라면 a.b?.c라고 써줄 수 있게 해준다. b에 값이 없다면 나머지 라인은 무시되고 nil이 반환된다.

 

⭐️ 7. try?와 try!: try를 쓸 때 에러를 잡거나 throw를 해야 했는데, try?의 경우에는 throwing function을 옵셔널 리턴 값으로 바꿔준다. 즉, 함수가 에러를 throw하면 결괏값으로 nil이 반환되고, 에러가 없는 경우에는 옵셔널로 래핑된 반환값을 돌려받게 된다. 한편, try!를 사용하면 함수에서 에러가 throw됐을 때 코드가 충돌하므로, 함수가 fail하지 않을 것임을 확신할 때만 써주자.

 

⭐️ 8. failable initializer: 제대로 동작할 수도, 아닐 수도 있는 이니셜라이저로, init() 대신 init?()으로 표시하며, 뭔가 잘못될 경우 nil을 반환한다. 나쁜 입력이 주어졌을 때 이니셜라이저를 동작하지 않게 하고 싶다면 failable initializer를 사용하면 된다.

struct Person {
	var id: String
	init?(id: String) {
		if id.count == 9 {
			self.id = id
		} else {
			return nil
		}
	}
}

⭐️ 9. typecasting: you can use typecasting to convert one type of object to another. as?를 사용한다.

class Animal { }
class Fish: Animal { }
class Dog: Animal {
	func makeNoise() {
		print("woof!")
	}
}

let pets = [Fish(), Dog(), Fish(), Dog()]

for pet in pets {
	if let dog = pet as? Dog {
		dog.makeNoise()
	}
}