ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift Enum - 1
    Programming/Swift(iOS) 2021. 4. 1. 20:53
    728x90

    지금부터는 swift에서 사용하는 enum타입에 대한 공부를 해볼까 합니다. 

     

    swift에서의 enum의 쓰임새는 다양합니다. 

    c와는 쓰임새가 정말 많이 달라서 처음에는 어렵게 느껴집니다. 

     

    제가 보는 책에서 swift enum을 유용하게 사용할 수 있는 경우를 찾아봤습니다.

    1. 제한된 선택지를 주고 싶을때 
    2. 정해진 값 이외에는 입력을 받고 싶지 않을때 
    3. 예상된 입력값이 한정되어 있을 때 

    -> enum은 하나를 선택하면 다른 하나를 선택 못하기때문에 Error 처리에서도 자주 등장합니다.

    Swift에서 자주 사용하는 Optional도 Enum으로 구현되어 잇습니다. 

     

    enum School {
    	case primary
        case elementary
        case middle
        case high
        case university
    }
    // 변수를 생성할때 타입을 명시해줬기 때문에 값할당시에 School을 생략 가능합니다.
    //var highestEducationLevel:School = School.middle
    var highestEducationLevel:School = .middle

     

    기본적인 예제를 설명하기 보다는 실전에서 사용하는 방법들에 대해서 적어볼까 합니다.

     

    enum은 상호 베타적입니다. 

     

    아래 예제에서 hasJoined과 hasLeft가 동시에 true로 설정될 수 있습니다. 

    struct Message {
        let userId:Int
        let contents:String?
        let data:Date
        
        let hasJoined:Bool
        let hasLeft:Bool
    }
    
    let joinMessage = Message(userId: 1, contents: nil, data: Date(), hasJoined: true, hasLeft: false)
    let textMessage = Message(userId: 1, contents: "Hello", data: Date(), hasJoined: false, hasLeft: false)
    let leftMessage = Message(userId: 1, contents: nil, data: Date(), hasJoined: false, hasLeft: true)
    
    //문제점: 잘못된 상태의 객체가 만들어질 수 있습니다.
    //join과 left가 둘 다 true인 경우가 있다.
    let wrongMessage = Message(userId: 1, contents: "Hi", data: Date(), hasJoined: true, hasLeft: true)
    

     

     

    위 부분을 enum으로 변환해보겠습니다. 

    참고로 enum의 case에는 tuple이 들어갈 수 있습니다.

    enum Message {
        case text(userId:Int, content:String, date:Date)
        case join(userId:Int, date:Date)
        case leave(userId:Int, date:Date)
    }
    
    //타입 추론이 가능하므로 Message.join이 아니라 .join만 사용해도 된다. 
    
    let joinMessage:Message = .join(userId:1, date:Date())
    let textMessage:Message = .text(userId:1, content:"Hello", date:Date())
    let leaveMessage:Message = .leave(userId:1, date:Date())
    
    
    // 넘겨진 enum값에 따라서 출력을 해주는 부분
    
    func logMessage(message:Message) {
        #if false
        switch message {
        case .text(userId: let userId, content: let contents, date:let date):
            print(userId, contents, date)
            break
        case .join(userId:let userId, date: let date):
            print(userId, date)
            break
        case .leave(userId:let userId, date:let date):
            print(userId, date)
            break
        }
        #endif
        #if false
        switch message {
        case .text(let userId, let content, let date):
            print(userId, content, date)
            break
        case .join(let userId, let date):
            print(userId, date)
            break
        case .leave(let userId, let date):
            print(userId, date)
            break
        }
        #endif
        #if false
        switch message {
        case let .text(userId, contents, date):
            print(userId, contents, date)
            break
        case let .join(userId, date):
            print(userId, date)
            break
        case let .leave(userId, date):
            print(userId, date)
            break
        }
        #endif 
    }
    logMessage(message:joinMessage)
    logMessage(message:leaveMessage)
    logMessage(message:textMessage)

    enum의 case로 test, join, leave을 나타낼 수 있어 확실하게 구분이 가능합니다. 

     

    logMessage함수를 보면 전달받은 message를 switch로 분기하면서 enum case에 대해서 처리를 합니다. 

    let에 대한 처리를 어디서 하느냐에 따라서 좀 더 축약형이 될 수가 있습니다.

     

    그렇다면  단일 항목에 대한 처리는 어떻게 할까요?

    아래와 같이 textMessage를 가져와서 case에 대한 단일 항목 처리를 하면 됩니다.

    if case .text(userId:let userId, content:let contents, date:let date) = textMessage {
        print(userId, contents, date)
    }
    
    if case .join(let userId, let date) = joinMessage {
        print(userId, date)
    }
    
    if case let .leave(userId, date) = leaveMessage {
        print(userId, date)
    }
    
    

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

    Swift Enum - 3  (0) 2021.04.01
    Swift Enum - 2  (0) 2021.04.01
    Swift Tuple  (0) 2021.04.01
    Swift 언어의 특징  (0) 2021.04.01
    Xcode CommandLine Project  (0) 2021.03.31
Designed by Tistory.