프론트엔드/Swift

[Swift] 옵셔널 변수와 상수 사용하기

dotudy 2024. 10. 9. 16:47

대표 이미지가 없어서.. 넣은 swift~

 

그동안 프로그래밍 언어를 배우면서 처음보는 개념이 등장했다. 대부분의 언어에 없는 개념이니 공부를 해보도록 하겠다.

 

옵셔널 타입은 변수 또는 상수에 값이 할당되지 않은 상황을 처리하기 위해 안전하고 일관된 접근 방식을 제공하는 것이다.

 

- 변수 선언 시 데이터 타입 annotation 다음에 '?'를 넣는다. 아래 보이는 예제는 index 변수에 정숫값이 할당되거나 아무런 값도 할당되지 않을 수 있다는 뜻이다. 내부적으로 컴파일러 관점에서 볼 때 값이 할당되지 않으면 nil(null)값이 저장된다.

var index: Int?

 

- 옵셔널에 값이 할당되었으면 "해당 값이 옵셔널 내에서 래핑(wrapped)되었다"라고 한다. 이 값을 사용할 때는 옵셔널 데이터 타입에서 옵셔널 이름 뒤에 '!'를 두어 추출하는 강제 언래핑(forced unwrapping)이 사용된다. 

var index: Int?

index = 2

var nameArray = ["Amy", "John", "Jane", "Kane"]

if index != nil {
	print(nameArray[index!])
} else {
	print("Index is nil")
}

 

index 뒤에 !를 두어 언래핑하였다. 위의 상황에서 index만 사용되었다면 error를 낸다.

 

- 강제 언래핑 대신 옵셔널 바인딩(Optional binding)을 사용하여 값을 임시 변수나 상수에 할당할 수 있다.

if let constantname = optionalName {
	// 옵셔널 상수가 값을 가지고 있는 경우 값을 할당
}

if var variablename = optionalName {
	// 옵셔널 변수가 값을 가지고 있는 경우 값을 할당
}

 

따라서 위의 코드는 다음과 같이 변경될 수 있다.

var index: Int?

index = 2

var nameArray = ["Amy", "John", "Jane", "Kane"]

if let myname = index {
	print(nameArray[index])
} else {
	print("Index is nil")
}

 

myname이라는 임시 상수에 index 변수의 값이 언래핑되어 할당된다. 

myname은 임시 값인데 if문 밖에서는 이 값이 사용될 수 없다. 따라서 옵셔널로 할당된 동일한 이름을 사용해도 된다. if let index = index라고 지정해도 상관이 없고 이를 생략해 if-let 구문이 사용된다.

 

* if-let 구문

var index: Int?

index = 2

var nameArray = ["Amy", "John", "Jane", "Kane"]

if let index {
	print(nameArray[index])
} else {
	print("Index is nil")
}

 

임시 값을 사용할 필요가 없는 여러 옵셔널을 작업하고 싶으면 다음과 같이 나열해서 사용하면 된다.

var pet1: String?
var pet2: String?

pet1 = "cat"
pet2 = "dog"

if let pet1, pet2 {
    print(pet1)
    print(pet2)
} else {
    print("another animal")
}

 

조건문을 사용하고 싶으면 옆에 추가로 나열해주면 된다. petnum값이 1보다 크지 않으면 해당 if문이 실행되지 않을 것이다.

 

var pet1: String?
var pet2: String?

pet1 = "cat"
pet2 = "dog"

if let pet1, pet2, petnum > 1 {
    print(pet1)
    print(pet2)
} else {
    print("another animal")
}

 

- 암묵적으로 언래핑(implicitly unwrapped)이 되도록 옵셔널을 선언할 수 있다. 이렇게 선언하면 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있다. '?' 대신 '!'를 사용하면 암묵적으로 언래핑된다.

 

var index: Int!  // 옵셔널이 암묵적으로 언래핑된다.

index = 2

var nameArray = ["Amy", "John", "Jane", "Kane"]

if index != nil {
	print(nameArray[index])
} else {
	print("Index is nil")
}

 

- 할당된 값이 없거나 nil을 할당할 수 있는 것은 옵셔널 타입뿐이다. 

스위프트에서 옵셔널이 아닌 변수 또는 상수에는 nil을 할당할 수 없다. 

var myInt = nil
var myString: String = nil
let myConstant = nil
// 모두 유효하지 않은 코드

 

모두 유효하지 않은 코드이기 때문에 컴파일 에러가 날 것이다. 옵셔널로 선언된 변수가 아니기 때문이다.