제목: Swift: When to use guard vs if


최근에 내 코드베이스에서 내가 느낀 것은 guard를 디폴트로 하냐, if를 디폴트로 하냐이다. 나는 그렇게 많이 생각하지 않고 guard로 바꾼다.

그러나 이것이 문제가 되기도 하는데, guardif에는 차이점이 있고, 어느것을 사용할 것인지 생각해볼 필요가 있는것 같다.

차이점은 미묘하지만 존재한다. guard는 어떤 값이 의도한것처럼 기능하길 원하도록 표현할때 사용된다.

예를들어 try! Swift app 에서 발표 세션 타입을 표시할때, 발표 타이틀이 세션 타이틀이다.



그러나 모든 세션이 발표를 가지는 것은 아니므로 프레젠테이션은 선택적이다. 사실 특정 세션 타입에서는 발표를 표시하고 타이틀을 가질거라 기대한다. 이때가 guard의 최고의 유스케이스이다!
@objc public enum SessionType: Int {
    case workshop
    case meetup
    case breakfast
    case announcement
    case talk
    case lightningTalk
    case sponsoredDemo
    case coffeeBreak
    case lunch
    case officeHours
    case party
}


public class Session: Object {
    // this is optional because not all sessions have presentations
    // e.g. no presentation during breakfast
    open dynamic var presentation: Presentation?
    // other properties here


    /** The main name of this session */
    public var formattedTitle: String {

        switch self.type {
        case .talk, .lightningTalk:
            // for the talk / lighting talk session type
            // we expect the presentation to be there
            // if it's not there, it's a fail, so guard is used
            guard let presentation = presentation else { return defaultTitle }
            return presentation.localizedTitle
        // other cases continued...
        }
    }
이 발표 타이틀은 항상 발표 세션 타입을 위해 표시될 수 있다. 만약 없다면, 실패한다. 이것이 이 경우에 왜 guard를 써야하는지의 이유이다.

그러나 다른 경우도 생각해보자. 쉬는시간세션(coffee break session)은 스폰서를 받을수도 있다. 이 경우, 쉬는시간의 타이틀에 스폰서 이름을 넣을 수 있다. 스폰서가 있으면 스폰서의 이름을 넣고, 없으면 넣지 않는 두가지가 다 맞는 경우이다. 이 경우가 if를 사용할 수 있는 경우다.
public class Session: Object {


    /** A sponsor, if any, responsible for this session. */
    open dynamic var sponsor: Sponsor?


    /** The main name of this session */
    public var formattedTitle: String {

        switch self.type {
        case .coffeeBreak:
            // some sessions are sponsored, some aren't
            // it's not a fail if there is no sponsor
            // so if is used
            if let sponsor = sponsor {
                return "Coffee Break, by \(sponsor.name)".localized()
            }
            return "Coffee Break".localized()
        // other cases continued...
        }
    }
@ecerney puts it so well의 말처럼, guard를 약한 Assert로 생각하면 된다.

if절처럼 guard는 불리언값의 표현에따른 상태를 실행한다. if절과는 다르게, guard절은 조건이 충족되지 않을때만 실행된다. guardAssert처럼 생각할 수 있는데, 크레쉬를 내버리는 Assert가 아니라 우아하게 빠져나올 수 있는 Assert이다.

그러니 guard를 쓰기전에 if를 생각해보자!


이 블로그는 공부하고 공유하는 목적으로 운영되고 있습니다. 번역글에대한 피드백은 언제나 환영이며, 좋은글 추천도 함께 받고 있습니다. 피드백은 

으로 보내주시면 됩니다.



WRITTEN BY
tucan.dev
개인 iOS 개발, tucan9389

,