상세 컨텐츠

본문 제목

[Day10] Optional (1)

Swift&SwiftUI

by (방울)도마토 2024. 4. 19. 14:55

본문

Optional

- 언어 차원에서 프로그램의 안전성을 높이기 위해 사용하는 개념 

- 'nil'을 사용할 수 있는 타입과 사용할 수 없는 타입을 구분하고, 사용할 수 있는 타입을 가리켜 Optional Type으로 부름 

 

nil 

- 순수하게 값이 없음

- 무엇인가 문제가 발생했을 때 이를 의미하기 위해 사용

ex) 딕셔너리에 잘못된 키(오타, 이미 삭제된 키)를 대입하는 경우 

    - 현재 키가 지금의 딕셔너리에 존재하지 않는다는 것을 알려주고 싶어하나, 오류를 발생시키는 것은 그다지 좋은 선택은 아님 

    - 잘못된 키 참조 하나 때문에 실행을 중단시키는 것은 안정성에 영향을 줌 

    - 결과값을 공백으로 반환할 수 없음 (자신의 실수를 인지하지 못하고 실제 키에 공백이 저장되어 있었다고 착각할 가능성)

→ 오류를 발생시키지 않고 뭔가 문제가 있었음을 알려주기 위해 nil 값을 반환 

 

- 오직 옵셔널 타입만이 nil을 반환할 수 있음 → 해당 값이 옵셔널 타입으로 정의되어 있어야 함 

- 오류가 발생할 가능성이 아주 조금이라도 있다면 모두 옵셔널 타입으로 정의하는 것이 좋음 

let num = Int("123") // 문자열 "123"이 정수형으로 형변환 
let num = Int("Swift") 
    // 일반 문자열은 숫자로 반환할 수 없음 -> 오류 발생!

- 대부분 프로그래밍 언어에서는 이런 상황을 오류로 처리하거나 혹은 예외 사항으로 처리 

     ex) NumberFormatException() in Java

- 스위프트의 경우 언어의 안정성을 위해 가급적 오류를 발생시키지 않으려고 노력 

    - 오류 발생시, 프로그램의 실행 흐름이 중단되고, 앱의 동작이 멈추거나 아예 꺼져버릴 수 있음 

    - 아무 값 특히, 0과 공백을 반환할 수는 없음 

        - Int("0")을 정상적으로 처리하는 경우, 문자열이 공백으로 처리되는 경우와 구분할 수 없음 

        ⇒ "값이 없음"을 의미하는 nil 을 반환 

 

 

Optional Type

- 일반 자료형에는 nil 값을 할당할 수 없으므로 nil을 반환하면 오류가 발생 

    → 옵셔널 타입 : nil을 저장할 수 있음 

⇒  오류가 발생할 가능성이 있다면 반드시 반환 타입을 옵셔널 타입으로 설정해야 함 

Optional() → nil 인 경우와 nil 이 아닌 경우 

- 반환하고자 하는 값을 옵셔널 객체로 다시 한 번 감싼 형태 

    - 성공한 경우 일반 값 반환, 그렇지 않으면 특수하게 처리된 예외나 NaN 값을 반환하는 다른 프로그래밍 언어와 다름 

 

Int("123") -> Optional(123)
    // Optional Wrapping : 처리가 성공적인 경우 실제 값이 옵셔널 타입으로 둘러싸임
    // Optional UnWrapping : 옵셔널 타입을 해체하고 실제 값을 추출하여 사용 
        // 처리 결과가 nil 값이 경우, 옵셔널 타입 해제 X
Int("안녕하세요") -> nil

 

Cf. 모든 값을 옵셔널 타입으로 선언하고 사용해도 되는가요?

- 일반 자료형에 nil 값을 대입할 수 있도록 허용하는 것

- 값을 사용할 때마다 값이 nil인지 아닌지 체크 → 프로그래밍 로직을 복잡하게 만듦

 

 

옵셔널 타입 선언과 정의

- 사용하는 자료형 뒤에 물음표만 붙이면 됨 

    ex) String? → Optional String, Int? → Optional Int

- String 타입에는 nil을 대입할 수 없지만, String? 타입에는 nil을 대입할 수 있음 

var optInt : Int?
var optStr : String?
var optDouble : Double?
var optArr : [String]?

var optDic : Dictionary<String, String>?
var optDic2 : [String:String]?

var optClass : AnyObject?

- 옵셔널 타입으로 자료형을 선언하면 자동으로 nil 초기화 

- 옵셔널 타입으로 선언된 변수나 상수에 실제 값을 할당하는 방법은 일반 타입과 동일

var optInt: Int?
optInt = 3

var optStr: String?
optStr = "Swift"

var optArr: [String]?
optArr = ["C", "JAVA", "Objective-C", "SmallTalk"]

var optDic = [String : Int]?
optDic = ["국어" : 94, "수학" : 88, "영어" : 96]

 

 

 

옵셔널 값 처리

ex. 생성자 Int(문자열) 

- 문자열 "123"이 입력되면 숫자로 변환할 수 있지만, 그럴 수 없는 일반 문자열이 입력되면 잠재적인 오류 가능성이 존재 

→ 옵셔널 타입의 정수값을 반환하도록 설계

extension Int {
	public init?(_ text: String, radix: Int = default)
}

- 옵셔널 타입으로 반환 → 결과값은 그 자체로 아무것도 할 수 없음 

    - 애초에 연산을 지원하지 않는 타입 

        - 옵셔널 타입과 일반 타입은 서로 연산할 수 없으며, 옵셔널 타입끼리의 연산이나 결합도 지원하지 않음 

 

 

Optional UnWrapping

관련글 더보기

댓글 영역