ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SWIFT] Enum #4
    iOS/SWIFT 2022. 9. 6. 16:56
    728x90
    반응형

    오늘은 열거형에 대해서 배워보겠다.

     

    enum

     

    우리는 변수나 상수를 선언할 때 그 데이터들의 묶음 형태로 많이 선언을 한다. (메서드,클래스,구조체 등등..) 하지만 이것들이 다 따로 있는 만큼 본인이 원하는 것을 각자의 개성에 따라 선택할 수 있는데 오늘은 먼저 열거형이다.  enum의 정의는 이렇다.

     

    된 값으로 이루어진 그룹을 공통의 형으로 선언하여 안전성을 보장하는 방법

     

    열거형이라니 말로는 감이 잘 오지 않으니 열거형 선언 방법에 대해 알아보자

    enum Rainbow{
    	case red
        	case orange
        	case yellow
    }

    이렇게 선언을 한다. 물론 저기 보이는 3개의 데이터들은 다 같은 타입이다. 하나라도 다르게 선언을 하면 오류가 생긴다. 정의에서 말한 것처럼 공용된 형태의 묶음이기 때문이다. 열거형은 원시값이 있는 경우와 없는 값으로 나뉘는데 지금과 같이 원시값을 선언을 안할 수도 있고

    enum Rainbow:String{
    	case red = "빨강색"
        	case orange = "주황색"
        	case yellow = "노랑색"
    }

    이렇게 초기값을 지정해도 된다.

    enum Rainbow{          
        case red,orange,yellow,green,blue,indigo,purple
    }
    
    var FavoriteColor = Rainbow.red		//red
    FavoriteColor = .indigo     		//indigo
    print("가장좋아하는 색은 \(FavoriteColor)")	// -> 가장좋아하는색은 indigo

    열거형으로 선언된 값을 변수에 저장한 뒤 출력하면 그값이 그대로 나온다.  원시값이 지정 되지 않으면 case이름으로 출력이 된다. 한번 열거형으로 초기화 된 변수는 이미 타입 추론으로 Rainbow형로 알고 있기 때문에 요소만 저장해줘도 문제가 없다.

     

    enum의 원시값(rawValue)

     

    위에서 원시값이라는 말을 했는데 제대로 설명은 안했다. 초기값과 비슷한 말인거 같기도 하고.. 여가서 자세히 설명을 하겠다. 일단 swift에서 enum은 배우 신기한 형태를 가진다. 예제를 한번 살펴보자

    enum Num:Int{
        case first = 1,second ,thrid
    }
    
    let ColorNum = Num.second.rawValue               
    print("\(FavoriteColor)는 \(ColorNum)번째 색깔이다")	// -> indigo는 2번째 색깔이다
    let color = Num(rawValue: 3)        
    print(color!)						// -> third

    enum형태인 Num은 정수형태의 열거형이고 first만 원시값을 가지고 있다. 하지만 ColorNum에는 second.rawValue로 저장을 하여 출력했더니 이게 왠걸 2가 알아서 출력이 되었다. 사실 마법이 아니라 이게 원시값 때문이다. 여기서 second.rawValue는 second의 원시값이라는 말인다. 이렇게 원시값은 특정 타입으로 지정된 값이기 때문에 원래 rawValue에서 1로 지정된 다음 값들은 모두 +1씩 저장이 되어 세팅이 되기 때문이다.

     

    그리고 Num(rawValue: 3)을 보면 optional 형태인걸 알 수 있는데 그 이유는 원시값을 가지지 않았기 때문에 nil을 반환하기 때문이다. 그래서 언래핑작업을 해줘야 사용할 수 있다. rawValue:3은 3을 가지고 있는 case이름을 출력하라는 말이기 때문에 third가 출력된다.

     

    원시값의 세팅은 Int형에서만 인정이 된다. Double이나 Float에서는 이렇게 처리한다.

    enum Num:Double{
        case first = 1.0,second = 2.0 ,thrid = 3, four
    }
    print(Num.four.rawValue)			// -> 4.0

    굿굿..!

     

    enum의 switch문

     

    다음은 열거형에서 메서드를 선언하여 switch문을 사용한 것이다. 이것을 함수형 enum이라고 한다.

    enum RainbowTranslation {       //함수형 enum
        case red(name: String)
        case orange(name: String)
        case yellow(name: String)
        case green(name: String)
        case blue(name: String)
        case indigo(name: String)
        case purple(name: String)
        
        func color() {          
            switch self{        
            case .red(let name):
                print(name)
            case .orange(let name):
                print(name)
            case .yellow(let name):
                print(name)
            case .green(let name):
                print(name)
            case .blue(let name):
                print(name)
            case .indigo(let name):
                print(name)
            case let .purple(name):     //위랑 같은 경우
                print(name)
            }
        }
    }
    
    let KoreanColor = RainbowTranslation.yellow(name : "노란색")   //yellow 맴버의 값 전달
    print(KoreanColor)						// -> yellow(name : "노란색")
    KoreanColor.color()						// -> 노란색

    위의 switch문은 enum에 색깔을 입력하면 출력하는 코드이다. 너무 간단한 코드지만 활용성이 뛰어날 것이다.

     

    재귀열거자

     

    재귀라는 말은 우리가 재귀함수를 배울때 많이 들어봤을 것인데 swift에서의 뜻도 동일 하다. 하나 이상의 열거형 case가 결합 값으로 또 다른 열거형 인스턴스를 가지는 열거형 이다.  컴파일러에게 재귀 열거자라는 것을 알려주기 위해서 indirect라는 키워드를 붙여야 사용할 수 있다. 한번 코드로 살펴 보자

    enum Calculate {
        case num(Int)
        indirect case add(Calculate,Calculate)                  
        indirect case division(Calculate,Calculate)             
    }

    이렇게 선언을 한다. 일단 enum의 모든 case가 재귀열거자일 경우 enum자체에 indirect를 붙여서 사용할 수 있다.  add와 divison은 안에 두 숫자가 들어갈 경우 그것을 연산하여 반환해주는 요소이다. 

    func Cal(_ operation:Calculate)->Int{           //_를 사용하면 맴버이름 사용안 할 수 있음
        switch operation{
        case let .num(value):
            return value
        case let .add(num1,num2):
            return Cal(num1) + Cal(num2)
        case let .division(num1,num2):
            return Cal(num1) / Cal(num2)
        }
    }

    메서드를 하나 선언 했다. enum에서 연산을 하겠다는 요소를 만들 었으니 연산을 해주는 메서드를 하나 선언해야한다. 메서드에 Calculate타입의 enum의 요소를 입력하면 그 값을 특정 연산을 하여 반환한다.

    let num1 = Calculate.num(30)
    let num2 = Calculate.num(6)
    let sum = Calculate.add(num1,num2)
    let result = Calculate.division(sum,Calculate.num(6))
    
    print(Cal(result))     //재귀 열거 때문에 알아서 모든 case문을 거치고 연산된 값으로 나옴
    			// -> 6

    값을 넣어준뒤 Cal메서드를 반환하면 간단한 계산기가 된다.

     

    전체코드

    enum Calculate {
        case num(Int)
        indirect case add(Calculate,Calculate)                  
        indirect case division(Calculate,Calculate)             
    }
    let num1 = Calculate.num(30)
    let num2 = Calculate.num(6)
    let sum = Calculate.add(num1,num2)
    let result = Calculate.division(sum,Calculate.num(6))
    
    func Cal(_ operation:Calculate)->Int{           
        switch operation{
        case let .num(value):
            return value
        case let .add(num1,num2):
            return Cal(num1) + Cal(num2)
        case let .division(num1,num2):
            return Cal(num1) / Cal(num2)
        }
    }
    print(Cal(result))

    'iOS > SWIFT' 카테고리의 다른 글

    [SWIFT] 연산프로퍼티 #6  (0) 2022.09.29
    [SWIFT] 클래스/구조체 #5  (0) 2022.09.13
    [SWIFT] Optional #3  (0) 2022.08.29
    [SWIFT] 조건문과 반복문#2  (0) 2022.06.30
    [SWIFT] 저장 프로퍼티#1  (0) 2022.06.17
Designed by Tistory.