ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift Optional - 1
    Programming/Swift(iOS) 2021. 4. 2. 08:19
    728x90

    swift에서 Optional은 '값이 있을 수도 있고 없을 수도 있다.' 입니다. 

    Optional은 nil을 안전하게 다루는 방법이라고 할 수 있습니다. 

     

    간단한 String optional입니다.

    var str1:String? = nil
    var str2:Optional<String> = ""
    
    print(str1)
    print(str2)
    
    print(str1?.isEmpty)
    print(str2?.isEmpty)
    
    /* 결과
    nil
    Optional("")
    nil
    Optional(true)
    */

    코드에서도 보듯이 optional의 nil과 isEmply와는 다릅니다. 

    str1과 str2의 isEmpty의 결과를 잘 보세요. nil과 true가 나옵니다. 

     

    즉 optional에 nil이면 아예 값을 할당 조차 안했다는 얘기가 됩니다. 

     

    Optional은  enum으로 구현되어 있습니다. 

    @frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
        case none
    
        case some(Wrapped)
    }

    값이 없으면 none이고, 있으면 some(Wrapped)형태로 저장이 됩니다. 

     

    아래 예제를 하나 더 보죠

    struct User {
        let id:Int
        let email:String
        let name:String? //optional<String> 형태이다.
        //let name:Optional<String>으로도 표현 가능
        let address:String?
    }
    
    let user:User = User(id: 0, email: "hello@gmail.com", name:"tom", address:nil)
    
    switch user.name {
    case .some(let value):
        print(value)
    case .none:
        print("none - nil")
    }
    

    case에서 let은 앞으로 빼도 되겠네요. 

     

    user를 아래와 같이 표시해서 사용할 수도 있습니다. 

    //둘중 하나만 nil이어도 수행 안된다.
    if let name = user.name {
        if let address = user.address {
            print("user \(name), address = \(address)")
        }
    }
    
    //optional binding
    if let name = user.name, let address = user.address {
        print("user \(name), address = \(address)")
    }
    
    //optional binding을 사용할 때 다양한 조건을 걸 수 있다.
    //nil과 ""은 다르다
    if let name = user.name, !name.isEmpty {
        print("\(name)이 제대로 입력되어 있습니다.")
    }

     

    User를 extension을 통해 좀 더 확장 시켜봅니다.

    extension User {
        //displayName은 name과 address로 결정된다
        #if false
        var displayName:String? {
            if let name = name, let address = address {
                return "\(name)/\(address)"
            }
            return nil
        }
        #endif
        
        //early exit, guard를 이용하면 가능하다.
        var displayName:String? {
            guard let name = name, let address = address else {
                return nil
            }
            return "\(name)/\(address)"
        }
    }
    

     

    func createWelcomeMessage(name:String) -> String {
        return "Welcome, \(name)"
    }
    if let displayName = user.displayName {
        let result = createWelcomeMessage(name: displayName)
        print(result)
    } else {
        let result = createWelcomeMessage(name: "guest")
        print(result)
    }
    
    //위의 코드는 nil 병합 연산자를 이용해서 간결하게 표현할 수 있다.
    //nil일때 기본값을 지정하기 위해 사용된다.
    
    //nil일때는 guest를 넣어줘라
    let displayName = user.displayName ?? "guest"
    let result = createWelcomeMessage(name: displayName)
    print(result)

    displayName 변수를 추가하고, 이 변수는 user의 name과 address의 영향을 받습니다. 

    그리고 createWelcomeMessage 함수를 통해서 현재 user가 누구냐에 따라서 어떤 메세지를 출력할 것인가 결정하는 것입니다. 

     

    nil 병합연산을 통해서 코드를 좀 더 간결히 줄일 수도 있습니다.

    'Programming > Swift(iOS)' 카테고리의 다른 글

    Swift 초기화 메서드  (0) 2021.04.02
    Swift Optional - 2  (0) 2021.04.02
    Swift Property - 3  (0) 2021.04.01
    Swift Property - 2  (0) 2021.04.01
    Swift Property - 1  (0) 2021.04.01
Designed by Tistory.