Swift enum과 옵셔널

  • 이번 글에서는 스위프트 언어에서의 열거형 enum과 옵셔널에 대해 알아보도록 하겠다.

열거형 enum

  • 열거형이란 그룹에 대한 연관된 값을 정의하고 사용하는 것이 가능한 타입을 말한다.
  • 단, 스위프트에서의 열거형 enum은 항목 그 자체가 고유의 값으로,
  • 해당 항목에 값을 매칭 시킬 필요가 없다.
  • 열거형 enum에는 원시값(rawValue)이라는 형태로 실제값을 부여할수도 있다.

열거형 문법

enum <열거형 이름>
{
    case <열거 항목1>
    case <열거 항목2>
    case <열거 항목3>
}
  • 즉, 다음과 같이 사용할 수 있는 것이다.
enum CompassPoint
{
    case north
    case south
    case east
    case west
}
    
var directionToHead = CompassPoint.west

열거형의 Switch문 사용

  • 다음과 같이 열거형을 switch문을 활용해 사용할수 있다.
  • 많은 경우, 열거형은 switch문과 함께 사용된다.
switch directionToHead
{
case .north:
    print("Lots of planets have a north")
case .south:
    print("Watch out for penguins")
case .east:
    print("Where the sun rises")
case .west:
    print("Where the skies are blue")
}

Associated Values

  • 열거형에는 다음과 같이 값을 지정하고 지정한 값을 불러올수도 있다.
enum Barcode
{
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}
    
// 연관 열거형 값 지정
    
var productBarcode:Barcode = Barcode.upc(8, 85909, 51226, 3)
    
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
    
// 연관 열거형 값 불러오기
switch productBarcode
{
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).)
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}

열거형의 원시값(Raw Values)

  • 다음과 같이 열거형에 원시값을 지정해줄수도 있다.
enum ASCIIControlCharacter: Character
{
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}
    
//Index 1씩 증가
enum Planet: Int
{
    case mercury=1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
    
//String은 기본 항목이 String으로 지정
enum CompassPoint: String
{
    case north, south, east, west
}

옵셔널

  • 지난 글의 스위프트 특이타입에서 nil은 아무것도 없는 상태라는 것을 알아봤다.
  • 변수만 선언되어 있고, 아직 인스턴스가 할당되기 전의 상태이다.
  • 옵셔널은 이러한 nil을 체크해서 에러가 발생하는 것을 막기 위해 사용한다.
  • 옵셔널은 두 가지 가능성을 가질 수 있다.
  • 한 가지는 값이 있음을 나타내는 nil이 아님을 확신하는 !와
  • 다른 한 가지는 nil의 가능성을 내포하는 ?이다.

옵셔널 타입

  • Int?, String?, Double? 등이 옵셔널 타입이다.
  • 이는 Int, String, Double과는 엄연히 다른 타입이다.
  • 옵셔널 타입은 unwrapping을 통해 사용될 수 있다.
  • Unwrapping 하는 방법에는 3가지가 존재한다.
  • forced unwrapping, optional binding, early exit

Forced unwrapping

func testFuc(optionalStr:String?) {    
    if optionalStr != nil {        
        let unwrapStr:String = optionalStr!        
        print(unwrapStr)        
    }    
}
  • 이는 옵셔널 변수의 값이 nil이 아니라면 !를 통해 옵셔널 변수를 문자열 변수로 변경하는 함수이다.

Optional binding

  • 옵셔널 바인딩은 if let이라는 스위프트의 새로운 문법을 통해
  • 만약 옵셔널 변수의 값이 nil이 아니라면 옵셔널 변수를 unwrapping 해주는 것이다.
func testFuc(optionalStr:String?)
{
    if let unwrapStr = optionalStr
    {
        print(unwrapStr)
    }
}

Early exit

  • guard let else문은 조건값이 거짓일때 실행된다.
  • 즉, 옵셔널 변수의 값이 nil 값이 대괄호안의 코드가 실행된다.
func testFuc(optionalStr:String?) {    
    guard let unwrapStr:String = optionalStr { return }    
    print(unwrapStr)    
    else 
}

Optional Chaining

  • 인스턴스의 프로퍼티나 메소드에 접근하기 위해 옵셔널 체인 연사자를 사용한다.
  • 다음과 같이 말이다.
var displayLabel: UILabel?
displayLabel?.text = “displayLabel에 옵셔널 체이닝 사용”

nil-coalescing

  • 이 기능으로 nil 값일 경우 기본값을 지정해 줄 수 있다.
  • ?? 기호를 사용한다.
let defaultImagePath = "/images/default.png"
let heartPath = imagePaths[“image”] ?? defaultImagePath

관련 글