🍫 notion으로 보기
*본 포스트는 애플의 'A Swift Tour'를 바탕으로 작성되었으며, 공부하며 기록용으로 작성한 포스트이기 때문에 정확하지 않은 정보가 있을 수 있습니다!
** notion으로 작성한 문서를 임시로 올려둔 포스트이기 때문에 사진 링크의 오류와 문서의 형식 등으로 인해 보시기에 불편함이 있을 수 있습니다. (사진이 안나오거나 코드를 보기 불편한 점 등은 빠른 시일 내에 수정하도록 하겠습니다!)
에러는 Error
프로토콜을 채택adopts하는 것으로 표현한다.
// 오류 종류 정의하기
enum PrinterError: Error {
case outOfPaper
case noToner
case onFire
}
**throw
, throws
****throw
:** 에러가 발생해서 에러를 던질 때(오류를 처리하는 곳으로 전달할 때)**throws
:** 에러를 낼 수 있는 함수를 마크할 때함수에서 에러를 던지고throw 싶으면, 함수는 즉시 반환을 하고 함수라고 불리던 코드는 에러를 처리handle한다.
func send(job: Int, toPrinter PrinterName: String) throws -> String{
if PrinterName == "Never Has Toner" {
throw PrinterError.noToner
}
return "Job sent"
}
do-catch
do
블록: try
를 사용하여 에러를 버릴 수 있는 코드를 마크한다.
catch
블록: 에서 에러의 다른 이름을 주지 않으면 에러는 자동적으로 error
라는 이름으로 받음.
do {
let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
print(printerResponse)
} catch {
print(error)
}
// PrinterName = "Bi Sheg" 이기 때문에 errorr가 나지 않고, "Job sent"가 출력된다.
// 콘솔창: Job sent
try
: 예외 상황을 다루기 위한 것. try한 메서드에 error가 발생하면 catch로 가서 처리한다.
try? try! 사용하는 것이 더 효과적이다. (← 여기에서는 do {try} catch {} 모두 적지 않아도 됨)
**experiment**
printer이름을 "Never Has Toner"로 바꾸고, 에러를 버리기 위해 send(job:toPrinter:) 함수 사용해라.
do {
// PrinterName을 바꾸기
let printerResponse = try send(job: 1040, toPrinter: "Never Has Toner")
print(printerResponse)
} catch {
print(error)
}
// "Never Has Toner"은 에러이기 때문에, catch로 가서 print(error)를 한다.
// 해당 에러는 throw PrintError.**noToner**
// 콘솔창: noToner
구체적인 에러를 처리하기 위해서 여러개의 catch
블럭을 사용할 수 있다. switch문
에서의 case
처럼 catch
뒤에 패턴을 적어주면 된다.
do {
let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")
print(printerResponse)
} catch PrinterError.onFire {
print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
print("Printer error: \(printerError).")
} catch {
print(error)
}
// console: Job sent
experiment
do 블럭에 에러로 전달하는 코드를 추가하라. 첫 번째 catch블럭으로부터 에러가 처리되기 위해서 어떤 종류의 에러 코드가 필요한가? 두 번째, 세 번째 블럭은 어떠한가?
try?
에러를 처리하는 다른 방법은 결과를 optional로 전환하기 위해 try?
를 사용하는 것이다. try?
에서 만약 함수가 error
로 전달되면, 특정 에러는 버려지고, 그 결과는 nil
이 된다. 그렇지 않으면 그 결과값은 그 함수가 리턴한 값을 가진 optional이다.
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
// job sent
let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")
// nil
defer
defer
함수에서 모든 함수를 실행한 후에, 함수가 리턴되기 직전에 실행되는 코드를 작성하기 위해 **defer**
을 사용하라. 코드는 함수가 에러로 던져졌는지와 상관없이 실행된다. setup / cleanup
코드를 작성하기 위해 defer
을 사용할 수 있다. (설사 그들이 다른 시간에 실행될 필요가 있다고 하더라도)
var fridgeIsOpen = false
let fridgeContent = ["Milk", "eggs", "leftovers"]
func fridgeContains(_ food: String) -> Bool {
fridgeIsOpen = true
defer {
fridgeIsOpen = false
}
let result = fridgeContent.contains(food)
return result
}
fridgeContains("banana") // false 반환
print(fridgeIsOpen) // false(defer 실행)
*.contain(element)
: 전달된 파라미터 값과 배열 안의 특정 원소가 일치할 경우 true
반환.
let result = fridgeContent.contains(food) → "banana"가 fridgeContent에 없으므로 **false**
반환.