Swift nil과 옵셔널 타입

  1. nil 이란? 다른 언어에서의 null 인 상태로 값이 할당되어 있지 않은 상태를 의미한다.
  2. 옵셔널 타입 : 일반 변수/상수는 nil 을 대입할 수 없기 때문에 이를 다루는 타입을 의미한다.
    1. 옵셔널 타입 사용 방법 : 타입 뒤에 ? 로 선언
      예) var optionalVar : Int?
    2. 옵셔널 타입의 특징
      1. nil 을 대입할 수 있다.
        예) var optionalVar : Int? = nil
      2. 자동 초기화가 가능한다.
        예) var optionalVar : Int? // nil 반환
    3. 옵셔널 타입의 객체 사용
      1. 옵셔널 타입 : nil 이거나 유효한 값
        1. nil 연산자 : ?? (기본값 설정 시 주로 사용)
          nill 연산자 ??
          var optionalStr : String?
          var colorName = optionalStr ?? "Blue"
          // optionalStr 값이 nil이면 colorName에 "Blue"를 저장
      2. 언래핑 : 옵셔널 타입의 변수에서 유효한 값 얻어오기
        1. if/guard 문을 이용하여 nil 을 검사한다.
          if/guard 문을 이용한 nil 검사
          1. if 문
          var optionalStr : String?
          if optionalStr != nil {
              print("nil이 아니다!")
          }
          else {
              print("nil 이다.")
          }

          2. guard 문
          func example() {
             var optionalStr : String?
             guard optionalStr != nil else {
                 print("nil 이다.")
             }
             print("nil이 아니다!")
          }
      3. 옵셔널 바인딩
        1. if 문을 이용한 옵셔널 바인딩
          if 문을 이용한 옵셔널 바인딩
          var optionalStr : String?
          if let realStr = optionalStr  {
              print("문자열의 값 \(realStr)")
          }
          else {
              print("문자열은 nil 이다.")
          }
        2. guard 문을 이용한 옵셔널 바인딩
          guard 문을 이용한 옵셔널 바인딩
          func example() {
             var optionalStr : String?
             guard let val = optionalStr, val != "" else {
                 return
             }
             print("val은 유효하고 빈 값이 아니다. \(val)")
          }
        3. 다중 바인딩, 함수호출
          다중 바인딩, 함수 호출
          if let val1 = someFunc(),
             let val2 = anotherFunc() {
             print("val1, val2는 유효한 값이다.")
          }
          else {
              print("val1, val2 중에 nil 값이 있다.")
          }
        4. 옵셔널 바인딩 체인
          옵셔널 바인딩 체인
          var optionalStr : String?
          if let val1 = optionalStr,
             let val2 = Int(val1) {
              print("val1은 정수로 변경가능한 문자열이다.")
          }
          else {
              print("val1은 정수로 변경 불가능하거나 nil이다.")
          }
      4. 옵셔널 체인 : 옵셔널 객체에 ? 기호를 직접 이용하며, 해당 객체가 nil 이면 진행하지 않고 nil 을 반환하고, nil 이 아니면 계속 진행(언래핑)
        1. 옵셔널 체인 시 유효한 값인 경우
          옵셔널 체인 시 유효한 값인 경우
          var optionalStr : String? = "Test"
          let str = optionalStr?.lowcased()
          print(str) // 결과는 옵셔널 "Test" 로 출력
        2. 옵셔널 체인 시 nil 인 경우
          옵셔널 체인 시 nil 인 경우
          var optionalStr : String?
          let str = optionalStr?.lowcased() // lowcased() 진행 안 함
          print(str) // 결과는 nil 출력
  3. 강제 언래핑 : nil 여부와 상관없이 강제로 언래핑 시도하며 타입 선언이나 옵셔널 체인에 사용 가능하나 nil 이면 런타임 에러가 발생하기 때문에 유효한 값이 반드시 들어가는 경우만 사용
    1. 강제 언래핑 사용 방법 : 옵셔널 타입으로 선언한 뒤에 사용 시에 ! 기호를 사용
    2. 강제 언래핑으로 옵셔널 타입 사용
      1. 사용 예시
        강제 언래핑 사용 예시
        var optionalStr : String? = "ABC"
        let str = optionalStr!.lowcased()
        // optionalStr 에 유효한 값이 들어갔기 때문에 정상 실행

        var optionalStr1: String?
        let str1 = optionalStr1!.lowcased()
        // optionalStr1 이 nil 이기 때문에 런타임 에러 발생

        let val = Int("A")! // 변환할 수 없기 때문에 런타임 에러 발생

        let dictionary = ["one" : 1. "two" : 2]
        let two = dictionary["two"]!
        // 딕셔너리에 원소가 있어서 정상 실행
        let three = dictionary["three"]!
        // 딕셔너리에 원소가 없기 때문에 런타임 에러 발생
    3. 암시적 언래핑 옵셔널 : ?, ! 기호 없이 직접 사용 가능하며, nil 인 경우 강제 언래핑과 마찬가지로 런타임 에러에 주의한다.
      1. 사용 예시
        암시적 언래핑 사용 예시
        let iuoStr : String! = "Hello, Swift"
        iuoStr.lowcased()
        // iuoStr 에 유효한 값이 들어갔기 때문에 정상 실행

        iuoStr = nil
        iuoStr.lowcased()
        // iuoStr 가 nil 이기 때문에 런타임 에러 발생