나의 발자취
열거형과 switch문 본문
열거형에 대한 구체적인 처리는 스위치문과 함께 쓸 때 사용성이 높아진다.
열거형은 한정된 사례로 만든 타입이고, 스위치문은 표현식에 대한 분기처리에 최적화 되어 있기 때문에 활용에 적합하다.
// 로그인 타입을 정의
enum LoginProvider: String { // 3가지로 정의
case email
case facebook
case google
}
let userLogin = LoginProvider.facebook
switch userLogin { // 3가지로 분기처리
case .email:
print("이메일 로그인")
case .facebook:
print("페이스북 로그인")
case .google:
print("구글 로그인")
}
// 물론 특정한 경우도 처리 가능
if LoginProvider.email == userLogin {
print("이메일 로그인")
}
1. 열거형에 연관값이 없고, 옵셔널 열거형의 경우
// 열거형의 선언
enum SomeEnum {
case left
case right
}
// 타입을 다시 옵셔널 열거형으로 선언 ⭐️
let x: SomeEnum? = .left
/**==================================================
[SomeEnum?의 의미] 옵셔널 열거형
- 값이 있는 경우 .some ===> 내부에 다시 열거형 .left /.right 이 정의되어있는 상태
- 값이 없는 경우 .none ===> nil
=====================================================**/
-> 열거형 안에 열거형이 있는 경우다!
// 원칙적으로는, 두 번 옵셔널 해제를 해주어야한다.
switch x {
case .some(let value): // Optional.some(let value) = Optional.some(SomeEnum.left) ⭐️
switch value {
case .left:
print("왼쪽으로 돌기")
case .right:
print("오른쪽으로 돌기")
}
case .none:
print("계속 전진")
}
하지만, 너무 불편하기 때문에!
// 편의적 기능 제공 ⭐️ -> 바인딩을 할 필요 없이 아예 괄호 안에다가 써서 동시에 벗길 수 있도록 하는 방법!
switch x {
case .some(.left):
print("왼쪽으로 돌기")
case .some(.right):
print("오른쪽으로 돌기")
case .none:
print("계속 전진")
}
대신, 열거형에 연관값이 없어야 한다.
// 전체적으로 full name으로 풀어서 쓴다면..
switch x {
case Optional.some(SomeEnum.left):
print("왼쪽으로 돌기")
case Optional.some(SomeEnum.right):
print("오른쪽으로 돌기")
case Optional.none:
print("계속 전진")
}
스위치문의 편의성
-> switch문에서 옵셔널 열거형 타입을 사용할때, 벗기지 않아도 내부값 접근가능
// 스위치문은 옵셔널 열거형 타입의 사용시, 편의성을 제공
switch x { // 예전에는 x! 라고 써줘야 했음 (스위치문에서 옵셔널 타입도 ok)
case .left:
print("왼쪽으로 돌기")
case .right:
print("오른쪽으로 돌기")
case nil:
print("계속 전진")
}
결국 스위치문은 옵셔널을 쉽게 사용하는 기능을 제공한다.
2. 열거형에 연관값이 있는 경우
1) 연관값(Associated Values)이 있는 경우와 switch문 (열거형 case 패턴) - Enumeration Case Pattern
/**==========================================
- 연관값이 있는 열거형의 활용 (열거형 case 패턴) ⭐️
- 구체적 정보(연관값)를 변수에 바인딩(let/var가능)하는 패턴
[열거형 case 패턴]
- case Enum.case(let 변수이름):
- case let Enum.case(변수이름):
[스위치문 뿐만 아니라, 조건문/반복문에서도 활용가능]
- 1) switch문 (대부분)
- 2) if / guard / for-in / while (필요한 경우)
===========================================**/
// 연관값이 있는 열거형 - 구체적인 정보가 연관값에 들어 있음
// 구체적인 정보를 꺼내서 사용해야하는, 로직 구현의 문제와 연관
enum Computer { // 3가지로 정의
case cpu(core: Int, ghz: Double)
case ram(Int, String)
case hardDisk(gb: Int)
}
var chip = Computer.cpu(core: 8, ghz: 3.1)
switch chip { // 수십가지로도 처리 가능 (필요한 처리 확장 가능)
case .cpu(core: 8, ghz: 3.1):
print("CPU 8코어 3.1GHz입니다.")
case .cpu(core: 8, ghz: 2.6):
print("CPU 8코어 2.6GHz입니다.")
case .cpu(core: 4, ghz: let ghz): // let ghz = 연관값 (cpu가 4코어인 경우, ghz에 저장된 연관값을 꺼내서 바인딩)
print("CPU 4코어 \(ghz)HGz입니다.")
case .cpu(core: _, ghz: _):
print("CPU 칩 입니다.")
case .ram(32, _):
print("32기가램 입니다.")
case .ram(_, _):
print("램 입니다.")
case let .hardDisk(gb: gB): // let gB = 연관값
print("\(gB)기가 바이트 하드디스크 입니다.")
default: // 대부분 default문이 필요하기도 함
print("그 외에 나머지는 관심이 없습니다. 그렇지만 칩이긴 합니다.")
}
// 연관값을 가지고 있는 열거형의 경우, 원하는 로직으로 잘 정의해서 처리해야하는 것에 주의
2) 연관값(Associated Values)이 있는 경우, if / guard / for-in / while 문 (열거형 case 패턴)
// 값 하나를 사용하기 위해서, 스위치문을 전체를 다 써야하는 불편함이 있었음
switch chip {
case Computer.hardDisk(gb: let gB): // let gB = 연관값
print("\(gB)기가 바이트 하드디스크임")
default:
break
}
위와 동일.
if 문에서도 case 활용이 가능하다. 이럴 때는 스위치문에서 콜론을 쓰는것과는 다르게 등호로 할당을 해주어야한다.
if case Computer.hardDisk(gb: let gB) = chip {
print("\(gB)기가 바이트 하드디스크임")
}
//:> 특정 케이스만 다루기 위해서 if문이나 반복문(for문) 사용 가능
chip = Computer.hardDisk(gb: 128) // 256
// if문에서도 스위치문에서 사용하는 case문과 같이 사용 가능 ⭐️
if case Computer.hardDisk(gb: let gB) = chip {
print("\(gB)기가 바이트 하드디스크임")
}
if case Computer.hardDisk(gb: let gB) = chip, gB == 256 { // if 문에서는 콤마를 쓰고 여러개의 조건문을 사용 가능.
print("256기가 바이트 하드디스크임")
}
let chiplists: [Computer] = [
.cpu(core: 4, ghz: 3.0),
.cpu(core: 8, ghz: 3.5),
.ram(16, "SRAM"),
.ram(32, "DRAM"),
.cpu(core: 8, ghz: 3.5),
.hardDisk(gb: 500),
.hardDisk(gb: 256)
]
for case let .cpu(core: c, ghz: h) in chiplists { // 배열중에서 특정 케이스만 뽑아서 활용 가능 ⭐️
print("CPU칩: \(c)코어, \(h)헤르츠")
}
=> CPU 케이스인 경우만 출력됨.
// 일반 for문과 비교 =====> 모든 경우가 출력
for chip in chiplists {
print("\(chip)")
}
열거형 케이스 패턴(for문) - 옵셔널타입 요소 배열
// 옵셔널 타입을 포함하는 배열에서 반복문을 사용하는 경우, 배열문 내부에 nil 인 경우도 다룰 수 있음.
let arrays: [Int?] = [nil, 2, 3, nil, 5]
for case .some(let number) in arrays { // some에 해당하는 경우만 사용하겠다=nil 은 버림
print("Found a \(number)")
}
// 출력결과는 2,3,5만 나온다.
'앱 개발 > iOS' 카테고리의 다른 글
@unknown 키워드 (0) | 2022.06.25 |
---|---|
옵셔널 (0) | 2022.06.25 |
옵셔널 타입의 내부 구조 (0) | 2022.05.27 |
열거형 (0) | 2022.05.27 |
컬렉션 관련 이론: KeyValuePairs, Copy-On-Write 최적화 (0) | 2022.05.26 |