본문 바로가기

비공개/공식문서 간단정리

[Swift] 옵셔널

 

옵셔널?

 

옵셔널은 값이 있는지 없는지 모름을 뜻한다.

값이 없을 수 있는 경우엔 옵셔널을 사용한다.

 

 

옵셔널은 2가지 가능성이 있는데

지정된 타입의 값이 있을 때 옵셔널을 풀어서 값에 접근하면

1. 해당 값이 있어서 액세스한다.

2. 해당 값이 없다.

 

 

값이 없을 경우의 예시로 String 값 -> Int 값으로 변화하는 초기화의 경우

일부 문자열만 정수로 변환 할 수 있다.

("ABC" : 변환x / "123" : 변환 O)

 

아래 코드에선 String -> Int 로 변화하는 초기화인데,

초기화가 실패 할 수 있으므로 optional(Int) 를 반환한다.

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 는  optional(123) 를 반환

 

 

옵셔널 타입을 작성하려면 타입의 이름 다음에 물음표(?)를 작성한다.

let myNumber: Int? // 어떠한 Int 값, 또는 값이 없음
let myText: String? // 어떠한 String 값, 또는 값이 없음

 

 


 

nil

옵셔널 변수에 특수한 값 nil 을 지정하면 값이 없는 상태를 나타낼 수 있다.

또한 기본값이 없이 옵셔널 변수를 정의하면, 이 변수의 값은 자동적으로 nil 로 설정된다.

 

var serverResponseCode: Int? = 404
print(serverResponseCode) // optional(404)

// serverResponseCode는 값이 없는 상태이다.
serverResponseCode = nil
print(serverResponseCode) // nil

/* ============================================================================ */

// answer의 값은 자동적으로 nil 로 설정된다.
var answer: String?

 

 

if 구문은 옵셔널과 nil 을 비교하여 옵셔널에 값이 있는지 확인 할 수 있다.

옵셔널에 값이 있다면 nil 과 "같지 않음" 으로 간주된다.

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

if convertedNumber != nil {
    print("convertedNumber은 빈 값이 아닙니다.")
    // convertedNumber은 빈 값이 아닙니다. 출력
}

 

 

옵셔널이 아닌 상수나 변수에는 nil 을 사용할 수 없다.

에상수 또는 변수가 특정 상황에서 값이 없이 동작하려면 적절한 타입의 옵셔널 값을 선언해야 한다.

옵셔널이 아닌 값으로 선언된 상수 또는 변수는 nil 값이 포함되지 않도록 보장된다.

 

 

💡 Swift 에서 nil특정 타입의 값이 없다는 의미이다.

모든 타입의 옵셔널은 nil 로 설정할 수 있다.

 

 


 

 

 

옵셔널 바인딩 (Optional Binding)

 

옵셔널 바인딩은 if, guardwhile 구문에서 옵셔널에 값이 있는지 체크하고

단일 동작의 일부로 상수 또는 변수로 추출 할 수 있다.

언래핑 방법 중 가장 많이 사용한다.

 

if 구문에서의 옵셔널 바인딩

let 옵셔널 숫자 = "123"

// 새로운 상수에 옵셔널 숫자에 포함된 값을 넣는다.
// Int(옵셔널 숫자) 에 의해 반환된 옵셔널 Int 에 값이 있을 경우 if문 안에 있는 코드 실행
if let 새로운 상수 = Int(옵셔널 숫자) {
    // * '새로운 상수'는 중괄호 안에서만 사용 할 수 있다.
    // * '새로운 상수'는 옵셔널에 포함된 값으로 초기화 되었으므로 옵셔널이 아닌 타입이다.
    // * '옵셔널 숫자'의 타입은 Int? 이고, '새로운 상수'의 타입은 Int 이다.
    
    print("옵셔널 숫자: \(옵셔널 숫자) 이고, 새로운 상수: \(새로운 상수) 입니다.")
    // 옵셔널 숫자: "123"이고, 새로운 상수: 123 입니다.
}

let possibleNumber = "123"
if let actualNumber = Int(possibleNumber) {  
    print("possibleNumber: \(possibleNumber) 이고, actualNumber: \(actualNumber) 입니다.")
    // possibleNumber: "123"이고, actualNumber: 123 입니다.
}

 

 

값에 접근한 후 기존 옵셔널 상수나 변수를 참조할 필요가 없다면

'같은 이름'으로 새로운 상수나 변수를 사용 할 수 있다.

 

let possibleNumber = "123"
let myNumber = Int(possibleNumber)

// 여기서의 myNumber 는 옵셔널 Int
if let myNumber = myNumber {
	// 여기서의 myNumber 는 옵셔널이 아닌 Int
	print(myNumber) // 123
}

// 위를 간소화 한 코드
if let myNumber {
	print(myNumber) // 123
}

 

 

💡 if 구문에서 옵셔널 바인딩으로 생성된 상수와 변수는 if 구분의 본문 내에서만 사용이 가능하다.

반대로 guard 구문에서 생성된 건 guard 구문 다음 코드에서 사용이 가능하다.

 

 


 

 

대체값 제공

nil-결합 연산자(??)를 사용하여 기본값을 제공하는 방법.

?? 의 왼편이 nil 이 아니면 왼편 값이 언래핑되고 사용된다.

그렇지 않으면 ?? 의 오른편 값이 사용된다.

 

let name: String? = nil
let greeting = "안녕 " + (name ?? "친구야") + "!"
print (greeting) // 안녕 친구야!
//  ?? 왼쪽에 있는 name 의 값이 nil 이기때문에, 오른쪽에 있는 "친구야" 가 출력

let name2: String? = "철수"
let greeting2 = "안녕 " + (name2 ?? "친구야") + "!"
print (greeting2) // 안녕 철수!
// ?? 왼쪽에 있는 name 이 nil 이 아니기 때문에, "철수" 가 언래핑 되어 사용됨

 

 


 

강제 언래핑

에러 또는 원치않는 상태와 같은 실패를 nil 로 표현하려면 옵셔널의 이름 뒤에 느낌표 (!) 를 추가하여 접근 할 수 있다.

강제 언래핑을 하면 언래핑된 값을 결과로 얻는다.

단, nil 값을 강제 언래핑하면 런타입 에러가 발생한다.

 

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

let number = convertedNumber!
print(number) // 123

 

 


 

 

암시적으로 언래핑된 옵셔널

옵셔널은 상수 또는 변수가 "값이 없음"을 허락하고 알려준다.

옵셔널이 값을 처음 설정하게되면 "항상 값이 있다" 로 가정 할 수 있으므로,

접근할 때마다 옵셔널의 값을 확인하고 언래핑 할 필요가 없다.

이러한 옵셔널을 암시적으로 언래핑된 옵셔널 이라고 한다.

 

타입 뒤에 느낌표로(String!) 암시적으로 언래핑된 옵셔널을 작성한다.

단, 나중에 변수가 nil 이 될 가능성이 있다면 암시적으로 언래핑된 옵셔널을 사용하면 안된다.

 

let possibleString: String? "안녕하세요"
let forcedString: String = possibleString // 언래핑이 필요하다.

let assumedString: String! = "반갑습니다"
let impliciString: String = assumedString // 자동으로 언래핑이 된다.

 

'비공개 > 공식문서 간단정리' 카테고리의 다른 글

[Swift] 산술 연산자  (0) 2023.12.13
[Swift] 대입 연산자  (0) 2023.12.13
[Swift] 튜플  (0) 2023.12.12
[Swift] 부울 (Booleans)  (0) 2023.12.12
[Swift] 정수와 부동 소수점 숫자  (0) 2023.12.12