본문 바로가기
Xcode/Swift - PlayGround

PlayGround)Enum의 활용

by 후르륵짭짭 2021. 9. 22.
728x90
반응형

 

안녕하세요! 짭짭이 입니다.

이전 보다 좀 더 빠르게 돌아왔습니다.

추석인데,,, 추석이 지나가고 있어서 슬픕니다 ㅠㅠ

8일 동안 쉬는데 ㅠㅠ 행복한데 ㅠㅠ

요즘엔 웹도 공부하고 있는데, 나중에 허접하지만 웹도 올려보도록 하겠습니다.

 

https://www.youtube.com/watch?v=tLcynwlNh38 

< Young K 노래 입니다 ㅎㅎㅎㅎ 노래방에서 부르고 싶은데 없네요,,,,>

 

1. 값으로서의 Enum


struct UserInfo{
    let id : String
    let name : String
}

enum Message {
    case join(UserInfo , Date)
    case text(UserInfo , String , Date)
    case quit(UserInfo, Date)
}

let defaultUser = UserInfo(id: "2015", name: "Zico")

let join : Message = .join(defaultUser, Date())
let text  = Message.text(defaultUser, "Hello world", Date())
let quit : Message = Message.quit(defaultUser, Date())

Enum은 그냥 Case로만 나누는게 아니라 값으로서 값을 가질 수 있습니다.

그래서 아래 처럼 분류가 할 수 있습니다.


func userState(message : Message) {

    switch message{

    case .join(let userinfo, let date): (1)
        print("Join User : id -> \(userinfo.id) name -> \(userinfo.name) \n Date : \(date)")
    case let .text(userinfo, message, date): (2)
        print("Text User : id -> \(userinfo.id) name -> \(userinfo.name) \n Date : \(date) \n Message : \(message)")
    case .quit(_ : let userinfo, _ : let date): (3)
        print("Quit User : id -> \(userinfo.id) name -> \(userinfo.name) \n Date : \(date)")
    }

}

userState(message: join)
// result
Join User : id -> 2015 name -> Zico 
Date : 2021-09-21 13:54:12 +0000

userState(message: text)
//result
Text User : id -> 2015 name -> Zico 
Date : 2021-09-21 13:54:12 +0000

Enum은 다음 처럼 Switch 문으로 케이스를 분류 해야하고 값이 존재한다면 다음 처럼 (1) ~ (3) 처럼 값을 사용 할 수가 있습니다.

그리고 이런 방식을 사용하면 쉽게 분류 할 수 있고 그 값을 읽어 올 수 있게 됩니다.

 

** 참고 **

enum Temp{
    case number(String)
}


func userStateWithIfCase(message : Message){

   (1) if case .join(let userInfo, let date ) = message { 
        print("[IfCase]Join User : id -> \(userInfo.id) name -> \(userInfo.name) \n Date : \(date)")
    }

   (2) if case let .text(user ,message ,sendTime) = message{
        print("[IfCase]Text User : id -> \(user.id) name -> \(user.name) \n Date : \(sendTime) \n Message : \(message)")
    }

    if case .number(let input) = Temp.number("Hello"){
        print(input)
    }

}

userStateWithIfCase(message: join)
//결과
[IfCase]Join User : id -> 2015 name -> Zico 
 Date : 2021-09-21 13:54:12 +0000
Hello

 

Case에 대한 분류는 if case 문으로 해줄 수도 있습니다.

분류 방식은 (1) ~ (2) 처럼 해줄 수 있고 message의 값이 .join과 같아면 {} 안의 내용을 수행 한다 입니다.

 

2. 상속의 대체제

 - 상속의 문제점 -


class Human{
    let name : String
    let id : String

    init(name : String , id : String){
        self.name = name
        self.id = id
    }

    func display(){
        print("\(name) / \(id)")
    }
}

class Student : Human{
    let school : String
    let grade : String

    init(school : String , grade : String , name : String , id : String){
        self.school = school
        self.grade = grade

        super.init(name: name, id: id) // Swift는 super.init()이 자신 클래스 정의 후 와야한다.
    }

    override func display() {
        super.display()
        print("\(school) \(grade)")
    }
}

class Worker : Human{
    let company : String
    let pay : Int

    init(company : String , pay : Int, name : String, id : String){
        self.company = company
        self.pay = pay

        super.init(name: name, id: id)
    }

    override func display() {
        super.display()
        print("\(company) \(pay)")
    }
}

let humans : [Human] = [
    Student(school: "Yale", grade: "Junior", name: "A", id: "2020"),
    Worker(company: "LG", pay: 4600, name: "B", id: "1090")
]

func displayAll(people : [Human]){

    people.forEach({ human in
        human.display()
        print("=============")
    })
}

displayAll(people: humans)
//결과
A / 2020
Yale Junior
=============
B / 1090
LG 4600
=============

// => 이런 상황인데, 만약 let name : String let id : String가 모두 각각의 클래스로 이동한다면 대대적인 공사가 발생한다.
//이런 상황일 때 Enum을 이용하면 극복이 가능하다.

위에는 상속방식으로 구조화 한 것 입니다.

해당 방식은 다형성을 가질 수 있다, 중복된 코드를 없앨 수 있다 등 

상속의 큰 장점을 가질 수 있지만, 경직된 구조화가 된다는 문제가 됩니다.

예를 들어 문서 변경으로 Human의 id가 개별 프로퍼티로 내려와야한다면

다 변경해야합니다. 아주 쉣입니다.

 

- Enum으로 해결 -

 


//이런 식으로 Enum case로 종속성을 만들 수도 있다.
//다만 이런 방식은 공통 부분에 대해서 처리를 할 수 없다는 점
//그리고 display와 같은 역할을 override가 아니라 분기 처리로 해결해야한다는 점
//그러나 경직된 구조가 아니라 자유롭게 생성할 수 있다는 점이 큰 장점이다.

enum HumanEnum {
    case student(StudentEnum)
    case worker(WorkerEnum)
}

struct StudentEnum{
    let name : String
    let id : String
    let school : String
    let grade : String
}

struct WorkerEnum{
    let name : String
    let id : String
    let company : String
    let pay : Int
}

let humansEnum : [HumanEnum] = [
    .student(  StudentEnum(name: "A", id: "2020", school: "Yale", grade: "Junior") ) ,
    .worker( WorkerEnum(name: "B", id: "1090", company: "LG", pay: 4600) )
]

extension HumanEnum{
    func display(){
        switch self{

        case let .student(student):
            print("Student \(student)")
        case let .worker(worker):
            print("Worker \(worker)")
        }
    }
}

for human in humansEnum{
    human.display()
}
//결과
Student StudentEnum(name: "A", id: "2020", school: "Yale", grade: "Junior")
Worker WorkerEnum(name: "B", id: "1090", company: "LG", pay: 4600)

Enum에 각각의 Case에 객체를 넣어서 값으롤 만들고 Enum에 함수를 만들어서 분기처리로 다형석 짝퉁을 만들어 줍니다.

위와 같은 방식은 확실히 상속의 장점을 살릴 수 없습니다.

하지만 경직된 구조가 아닌 구조화를 할 수 있습니다.

 

3. RawValue의 Enum


enum FoodType : String{ //Enum에 String을 넣어주면 해당 case가 String의 RawValue를 가지게 된다.
    case korean
    case japan
    case china

    // 실패할 경우, nil을 반환하는 초기화 메소드
    init?(rawValue: String) {
        switch rawValue.lowercased() {

        case "kimch" , "bulgogi" :
            self = .korean
        case "ramen" :
            self = .japan
        case "trash" :
            self = .china

        default :
            return nil
        }
    }

}

func returnFoodType(food : String) {
    guard let type = FoodType(rawValue: food) else{
        print("음식이 없어요")
        return
    }

    print(type)
}

returnFoodType(food: "kimch")
//결과
korean

이렇게 RawValue로 Enum을 사용하면 분기 처리를 좀 더 구조적으로 할 수 있습니다.

 

지금까지 Enum에 대해 알아봤습니다.

정말 Swift에서는 Enum을 취미로 잘 사용해서,,,, 많이 알아 둬야할 것 같습니다.

 

감사합니당~~~

728x90
반응형

댓글