CustomStringConvertible
프로토콜을 준수하는 Type은 인스턴스를 문자열로 변환할 때 사용할 고유한 표현을 제공할 수 있습니다.CustomStringConvertible
을 준수하는 경우, String(description:) Initializer 및 Print(_:) 함수는 인스턴스의 사용자 지정 설명 속성을 사용합니다.CustomStringConvertible
을 일반 제약 조건으로 사용하는 것은 허용되지 않습니다.struct Student: CustomStringConvertible{
let name: String
let age: Int
var description: String {
return ("나는 \(name)이고, \(age)살입니다")
}
}
let kane: Student = Student(name: "kane", age: 100)
print(kane) // 나는 kane이고, 100살입니다
스위프트에서 오류는 Erro라는 프로토콜을 준수하는 타입의 값을 통해 표현된다. 사실상 요구사항이 없는 빈 프로토콜일 뿐이지만, 오류를 표현하기 위한 타입(주로 열거형)은 이 프로토콜을 채택한다
enum FruitJuiceError: Error {
case outOfStock
case unknownError
} // 이처럼 오류의 종류를 표현하는 것이 일반적이며 편리한 방법이다
오류를 던지게 되면 프로그램의 흐름이 바뀔 가능성이 크기 때문에 어디서 오류를 던지고 받을지 결정하는 것이 매우 중요하다.
try 키워드를 통해서 던져진 오류를 받을 수 있다. try
는 try?
또는 try!
등으로도 표현할 수 있다.
함수, 메서드, 이니셜라이저는 throws 키워드를 매개변수 뒤에 작성해서 오류를 던질 수 있다.
ex func makeJuice(_ fruit: Fruit) throws {
throws는 함수 메서드의 자체 타입에도 영향을 미친다. 그래서 throws를 포함한 함수, 메서드, 이니셜라이저는 일반 함수, 메서드, 이니셜라이저로 재정의가 불가하다!!!!!
but, 포함 안한 것들은 한 것으로 재정의가 가능하다
그리고 오류를 던질 가능성이 있는 메서드를 호출하는 함수도 또한 오류를 던질 수 있어야 한다.
하지만 이렇게 알리기만 하고 오류가 발생한 후에 적절한 처리를 해주지 않으면 다음 코드가 정상적으로 동작하지 않는다.
2. do-catch 구문을 이용하여 오류처리
do
내부의 코드에서 오류를 던지면 catch
절에서 오류를 전달받아 적절이 처리해주면 된다
do {
try 오류가 발생 가능한 코드
오류가 발생하지 않으면 실행할 코드들
} catch 오류 패턴1 {
처리 코드
} catch 오류 패턴2 where 추가 조건 {
처리 코드
} // 오류의 종류를 명시하지 않으면 코드 블록을 생성할 때 내부적으로 error 라는
//이름의 지역 상수가 오류의 내용으로 들어온다.
이렇게 하면 오류를 받아서 다시 던지던 함수들
3. 옵셔널 값으로 오류 처리
try?
를 사용하여 옵셔널 값으로 변환하여 오류를 처리할 수 있다.
func optionalThrowFunction(isReal: Bool) throws -> Int {
if isReal {
throw SomeError.unknownError
}
return 1
}
let x: Optional = try? optionalThrowFunction(isReal: true)
print(x) // nil
let y: Optional = try? optionalThrowFunction(isReal: false)
print(y) // Optional(1)
4. 절대로 발생하지 않을 것이라고 확신
이 방법은 강제추출 옵셔널 바인딩과 비슷한 느낌이다. 만약 try!
를 사용하였는데 오류가 발생하면 런타임 오류가 발생하여 프로그램이 강제로 종료된다
전체적인 느낌은 이제껏 프로퍼티에서 사용했던 willSet 과 didSet의 느낌이다