Swift - Enumeration (열거형)
An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.
Swift의 열거형은 C나 C++ 처럼 0을 기본 값으로 갖지 않는다.
enum CompassPoint {
case north
case south
case east
case west
}
enum 타입의 변수를 선언할 때는 CompassPoint.east
라고 해도 되고 goEast
처럼 이미 타입을 지정한 경우는 .east
만써도 컴파일러가 알게 된다
var goSouth: CompassPoint = CompassPoint.south
var goEast: CompassPoint = .east
위에서 지정한 값을 print하면 각각 south, east 가 찍히게 된다
결국 별도 값을 지정하지 않아도 이름이 값이 된다는 사실을 알 수 있다
print(goSouth) // Prints south
print(goEast) // Prints east
Enum initialize raw value
그럼 값을 지정하려면 어떻게 하나?
swift enum에는 rawValue(원시값) 을 사용하여 값을 초기화할 수 있다
예를 들어 아래와 같이 CompassPoint
가 Int 값을 가지게 한다면 순서대로 0~3 의 값을 갖는다
중간에 생략해도 알아서 값이 초기화된다. 순서대로 말고 각 다른 값을 넣을거라면 각각 값으로 초기화한다.
enum CompassPoint: Int {
case north = 1 // 첫 번째 값에 1이 대입되어 밑은 2, 3, 4 로 대입된다
case south
case east
case west
}
Int 는 순서가 명확하게 0 1 2 로 되지만 0.0 으로 초기화한다면 0.0다음에 0.1이 올지, 1.1이 올지, 0.01이 올지 컴파일러는 판단할 수 없다
그런 값은 각 case 별로 초기화가 필요하다
만일 “A”로 초기화하면 어떻게 될까? B, C, D 순으로 될까?
enum CompassPoint: String {
case north
case south
case east = "E"
case west
}
var goSouth: CompassPoint = CompassPoint.south
var goEast: CompassPoint = .east
print(goSouth.rawValue) // Prints south
print(goEast.rawValue) // Prints E
이미 CompassPoint.south가 string이므로 이름이 값으로 초기화된다
Associated Values (연관값)
각 하나의 타입에 대해 인스턴스마다 다른 값을 가지게 할 때 사용한다
Swift 공식 문서에는 바코드 예제로 이것을 설명한다
1.바코드는 크게 1차원 바코드와 2차원 바코드인 QR코드로 나뉜다.
2.1차원 바코드는 12자리 숫자를 표현한다
3.2차원 바코드는 임의의 문자열을 표현할 수 있다
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 1434, 34324, 3)
productBarcode = .qrCode("ADSFAFDASDF")
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC \(numberSystem) \(manufacturer) \(product) \(check)")
case .qrCode(let productCode):
print("QR \(productCode)")
}
Switch case + enum
switch case에 enum을 결합해서 사용하면 enum에서 생성한 case에 대해서만 분기를 탈 수 있게 한다
이 경우는 switch case 의 default 는 실행되지 않기 때문에 @unknown default:
을 추가하여 할당되지 않은 값이 들어올 때 처리를 할 수 있다
switch goEast {
case .north:
print("let's go north")
case .south:
print("let's go south")
case .east:
print("let's go east")
case .west:
print("let's go west")
@unknown default:
print("I can't go anywhere")
}
Iterating over Enumeration Cases
Enum에는 CaseIterable
protocol을 채택할 수 있다. allCases
로 값 모음에 접근할 수 있다
모든 항목에 접근할 수 있다는 말
var directions = CompassPoint.allCases.count
print("In the Earth have \(directions) directions")
allCases 로 enum의 모든 case에 쉽게 접근할 수 있다
for direction in CompassPoint.allCases {
print(direction)
}
let _ = CompassPoint.allCases.map {print($0)}
CaseIterable (protocol)
A type that provides a collection of all of its values.
위에서 나온 CaseIterable 프로토콜을 살펴보자.
이 프로토콜은 enum에서 주로 사용한다. allCases
속성을 사용 해 모든 케이스에 접근할 수 있다
'Programming > Swift' 카테고리의 다른 글
[Swift] Computed Properties (연산 프로퍼티) (0) | 2019.07.28 |
---|---|
[Swift] Lazy Stored Properties (0) | 2019.07.28 |
[Swift] Properties 1 - Stored properties (저장 프로퍼티) (0) | 2019.07.09 |
[Swift] Swift Any, AnyObject 차이 알아보기 (0) | 2019.06.12 |
[Swift] Swift 언어의 특징 - 강한 타입 (0) | 2019.06.11 |