익스텐션?
기존의 클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가하는 기능
- 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티
- 타입 메서드 / 인스턴스 메서드
- 이니셜라이저
- 서브스크립트
- 중첩 타입
- 특정 프로토콜을 준수할 수 있도록 기능 추가
연산 프로퍼티가 제일 많이 사용됨
extension Int {
var isEven: Bool {
return self % 2 == 0
}
var isOdd: Bool {
return self % 2 == 1
}
}
var number = 3
number.isOdd // true
number.isEven // false
extension String {
func convertToInt() -> Int? {
return Int(self)
}
}
var string = "0"
string.convertToInt() // Int(0)
열거형
연관성이 있는 값을 모아 놓은 것을 말한다.
ex) 계절
// 대문자로 시작해야함
enum CompassPoint {
// 한줄로도 가능
// case north, south, east, west
case north
case south
case east
case west
}
var direction = CompassPoint.east
direction = .west // 열거형 이름을 추론해서 내부 이름을 바로 찾을 수 있음
switch direction {
case .north:
print("north")
case .south:
print("south")
case .east:
print("east")
case .west:
print("west")
}
원시값을 가지게 구성할 수 도있다.
enum CompassPoint: String {
case north = "북"
case south = "남"
case east = "동"
case west = "서"
}
switch direction {
case .north:
print(direction.rawValue)
case .south:
print(direction.rawValue)
case .east:
print(direction.rawValue)
case .west:
print(direction.rawValue)
}
let direction2 = CompassPoint(rawValue: "남")
열거형의 연관값
enum PhoneError {
case unknown
case batteryLow(String)
}
let error = PhoneError.batteryLow("배터리가 곧 방전됩니다.")
switch error {
case .batteryLow(let message):
print(message)
case .unknown:
print("알 수 없는 에러입니다.")
}
옵셔널 체이닝
옵셔널에 속해 있는 nil 일지도 모른느 프로퍼티, 메서드, 서브스크립션 등을 가져오거나 호출할 때 사용할 수 있는 일련의 과정
struct Developer {
let name: String
}
struct Company {
let name: String
var developer: Developer?
}
var company = Company(name: "Gunter", developer: nil)
print(company.developer) // error
var developer = Developer(name: "han");
var company = Company(name: "Gunter", developer: developer)
print(company.developer.name)
// 옵셔널이기때문에 옵셔널을 벗겨야한다. 그런데 이 방법은 번거롭고 다른 방법이 추가적으로 있다
print(company.developer?.name) // nil 이 될 수 도있으므로 error
print(company.developer!.name)
에러처리
1급 클래스를 지원함
- 발생 (throwing)
- 감지 (catching)
- 전파 (propagating)
- 조작 (manipulating)
에러프로토콜 채택한 열거형
enum PhoneError: Error {
case unknown
case batteryLow(batteryLevel: Int)
}
throw PhoneError.batteryLow(batteryLevel: 20)
오류를 처리하는 방법
- 함수에서 발생한 오류를 해당 함수에 전달
function checkPhoneBatteryStatus(batteryLevel: Int) throws -> String { // 반환값이 있다면 throws -> 반환 형
guard batteryLevel != -1 else { throw PhoneError.unknown }
guard batteryLevel >= 20 else { throw PhoneError.batteryLow(batteryLevel: 20) }
return "배터리 상태가 정상입니다."
}
// 위함수는 오류를 던져줄 수도있기 때문에
/*
do {
try 오류 발생 가능 코드
} catch 오류 패턴 {
처리코드
}
*/
do {
try checkPhoneBatteryStatus(batteryLevel: -1)
} catch PhoneError.unknown {
print("알 수 없는 에러입니다.")
} catch PhoneError.batteryLow(let batteryLavel) {
print("배터리 전원 부족 남은 배터리: \(batteryLevel)%")
} catch {
print("그 외 오류 발생: \(error)")
}
let status = try ? checkPhoneBatteryStatus(batteryLevel: 30)
prtint(status)
let status2 = try! checkPhoneBatteryStatus(betteryLevel: 30)
print(status2)
try!
는 에러를 내지 않는 것을 개발자 확실하게 알수있다면 사용한다 하지만 에러를 내면 애플리케이션이 종료된다.