하루를살자

Swift - Enum 본문

Swift

Swift - Enum

Kai1996 2021. 12. 31. 03:14

Enumerations

  • Enumeration cases can specify associated values of any type to be stored along with each different case value.
  • You can use 'case' keyword to introduce new enumeration cases.
  • Each enumeration definition defines a new type. 

var directionToHead = CompassPoint.west 

directionTohead = .east 

 

  • The type of directionTohead is already known, so its type can be dropped when setting its value. ==> This makes for highly readable code when working with explicitly typed enumeration values
    enum CompassPoint {
        case north
        case south
        case east
        case west
    }
    
    var directionToHead = CompassPoint.west 
    
    //The type of directionToHead is assigned as above, therefore, its type can be omitted.
    directionToHead = .east

Matching Enumeration Values with a Switch Statement​

  • Switch 문의 case 에 해당 열거형의 모든  case 가 없다면, Switch 문의 특성인 exhausitveness 때문에 컴파일 에러가 발생하는데, 이는 default 문을 넣어줌으로써 해결할수있다. 

 Iterating over Enumeration Cases 

enum 의 변수명을 "CaseIterable" 이 conform 하게 함으로써, swift 는 모든 case 들에 allCases 프로퍼티 라는 이름으로 만들고, 이는 아래와 같이 사용될수 있음.

enum Beverage: CaseIterable {
	case coffee, tea, juice
} 

let numberOfChoices = Beverage.allCases.count 
print("\(numberOfChoices) beverage available !") 

//For in loop 
for beverage in Berverage.allCases {
	print(beverage) 
}​

 

 

 Associated Values 

  • enum 형에서 각각의 case 들에게 상수나 변수로 값을 지정 시켜줄수 있는데, 추가 정보를 담는 값 "associated value" 를  case 변수 옆에 선언 할수 있다. 
  • 예제로 물건의 바코드가 두가지 종류, upcFormat 과  qrFormat 으로 이루워 져있다고 생각해보자.
  • -  UPC  포맷은 0부터 9까지의 Integer 가 첫번째에 는 system digit,  두번째 는 5개의 숫자로 이루어진 manufacturer code, 세번째는 product code, 마지막으로 check digit 으로 이루어 져있다
  • - QR 포맷은 최대 2,953 개의 알바뱃의 갯수를 가지고 있는 바코드이다. 
  • 이를 열거형으로 표현하면 아래와같이 표현 할수있다.  
  • enum Barcord { case upcFormat(Int, Int, Int, Int) case qrFormat(String) }

--> 위의 열거형 선언은 실질적인 Int 와 String 의 값을 주지않는다 -> 이렇게 명시해놓은것은 Barcode.upcFormat 이나 Barcode.qrFormat 이 저장할 값의 타입을 지정해놓은것이다. 

example) 

// Create a variable that is assigned with a value of Barcord upcFormat with an 
// associated tuple value of (8,85909,51226,3)
var productBarcode = Barcode.upcFormat(8, 85909, 51226, 3) 


//위의 productBarcode 를 qrFormat 으로 변경 
productBarcode = .qrFormat("ASDKJNIJSDF")

Matching Enumeration Values with a Switch Statement​ 에서 보았던것처럼 열거형을 Switch 문을 통해서 어떤 바코드 format 으로 이루어 져있는지 확인할수있는데, 이번에는 각각의 case 에 associated values 를 추출해볼 것이다. (추출은 var 또는 let  prefix 를 쓰고  switch 의 case 문 body 안에서 사용가능하다).

switch productBarcode {
	case .upFormat(let numberSystem, let manufacturer, let product, let check): 
    	print ("UPC : \(numberSystem), \(manufacturer), \(product) , \(check))"
    case .qrFormat(let productCode) :
    	print ("QR CODE : \(productCode)")
}

//만약 추출된 변수들을 모두 상수나 변수로 통일해서 사용한다면, 아래와같이 간결하게 표현가능

switch productBarcode {

	case let .upFormat(numberSystem, manufacturer, product, check): 
    	print ("UPC : \(numberSystem), \(manufacturer), \(product) , \(check))"
    case var .qrFormat(productCode) :
    	print ("QR CODE : \(productCode)
}

 

 Raw Values 

  • 위의 예시에서는 Associated value 가 각각의 case 에 선언 되어서 다른 타입들의 값들을 저장할수 있었다. 이러한 목적을 이루는 다른 방법으로 , 각 case 에 같은 타입 의 값을 미리 각각 지정해줄수있는데 이 값들을 raw value 라고 부른다. 

아래의 예제는 raw ASCII 값을 열거형의 case 에 미리 지정해놓은것이다. 

enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}
  • Raw value 는 String, character, integer, float 이 될수있다. 
  • 각각의 Raw value 는 unique 해야한다.

*Note : Raw Value vs Associated Value

 Raw value 와 Associated value 가 헷갈릴수도 있는데, 이렇게 이해 해보자. 

--> Raw Value 는 열거형을 만들때, 미리 각 case 에 값을 선언해 주는것이고, 이값은 변하지 않는다 (상수로 지정됨).

--> Associated Value 는 새로운 상수나 변수에 열거형의 case 중에 하나를 지정하여  생성하므로, 생성할때마다 다른값들을 넣어줄수있다.

 

Implicitly Assigned Raw Values 

  • Raw values 를 가지고 있는 열거형 을 사용할때 case 하나하나 값을 지정안해줘도 Swift 가 자동적으로 값을 지정해준다. 

Example 1) 

- Raw Value 의 타입이 Integer 일때, 첫번째 case 의 값에 1 을 넣으면, 그 뒤의 case 들의 raw value 의 값은 1이 증가한 값을 가지게 된다. 

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

-> 위 의 예제는 태양으로 부터 행성의 순서를 나타내는 열거형 이고, mercury 의  raw value 가 1 로 explicity defined (명시적으로 지정) 되어 있는 볼수 있고, venus 의 값은 2, earth 의 값은 3 과 같은 식으로 nepturne 까지 전파된다. 

-> 만약 mercury 의 Raw Value 가 명시적으로 지정이 되지 않았다면 0 부터 7 까지의 raw value 가 각각의 행성의 raw value 에 지정이 되었을 것이다. 

 

Example 2 )

- Raw Value 의 타입이 String 일때, 각각의 case 의 text가 raw value 로 지정이 된다. 

enum CompassPoint: String {
    case north, south, east, west
}

-> 여기서는 case north 의 raw value 는 "north", case south 는 "south" .... 와 같은 패턴으로 이어진다.

 

Raw value 접근방법 

  • rawValue 프로퍼티를 사용해 접근가능

ex) let earthsOrder = Planet.earth.rawValue 

 

Initializing from a Raw Value

  • 만약 열거형을 raw value 타입으로 지정했다면, 그 열거형은 자동적으로 raw value 의 타입을 가지
  • .고 initializer 초기값 생성기? 를 받고 해당하는 case 나 nil 을 리턴해준다. 우리는 이 초기값 생성기를 이용하여 새로운 열거형의 인스턴스를 만들수도 있다. 

Example ) 

let possible Planet = Planet(rawValue: 7) 
//possiblePlante is of type Planet? (Optionals)  and equals Planet.uranus
  • 하지만 만약 내가 원하는 rawValue 의 case 가 없다면 초기값 생성자는 optional enumeration case 를 항상 리턴해주기 때문에 nil 값을 리턴 받을것이다.

Example) 

let positionToFind = 11
if let somePlanet = Planet(rawValue: positionToFind) {
    switch somePlanet {
    case .earth:
        print("Mostly harmless")
    default:
        print("Not a safe place for humans")
    }
} else {
    print("There isn't a planet at position \(positionToFind)")
}
// Prints "There isn't a planet at position 11"

--> optional binding 사용 

 

 

 

 

'Swift' 카테고리의 다른 글

Swift 고차함수  (0) 2022.02.05
Swift - Collection Types  (0) 2022.01.01
Swift - Optionals  (0) 2021.12.21
SwiftUI Architecture - MVVM (Model, View, and ViewModel)  (0) 2021.12.20
Swift Basics - Playground(Xcode), Data type, Function  (0) 2021.12.17
Comments