간략한 스위프트 문법 정리
🧐 [var, let, Tuples] (변수, 상수, 튜플)
📎 변수, 상수 선언 방법
// 변수
var str = "Hello"
var age = 10
// 상수
let name = "MCH"
let year = 2022
변수/상수의 타입을 미리 지정해놓지 않아도, 타입 추론(Type Inference)을 통해 변수/상수의 타입을 자동으로 지정해준다.
위 방법은 편리하지만, 예상하지 못한 문제를 야기할 수도 있으므로 타입 어노테이션(Type Annotation)을 통해
변수/상수의 타입을 개발자가 미리 지정해주는 것이 좋다.
// 타입 어노테이션(Type Annotation)
var str: String = "Hello"
let height: Float = 180.0
var isSuccess: Bool = false
📎 강타입(Type-safe) 언어, 형변환(Type-conversion)
스위프트는 타입에 대해 엄격하다. 그래서 type-safe 언어 라고 부른다.
스위프트에서는 서로 다른 타입의 변수끼리는 값의 교환을 엄격하게 제한하고 있다.
따라서, Double 타입의 변수에 들어있는 6.0 이라는 값을 Int 타입의 변수와 덧셈 연산을 하려면
반드시 형변환을 명시적으로 개발자가 해줘야만 한다. "암시적 형변환을 허용하지 않는다"는 얘기이다.
// Double, Int 의 형변환 예시
var testDouble: Double = 6.0
var testInt: Int = 10
print(testInt + testDouble) // 에러 발생.
print(testInt + Int(testDouble)) // 출력: 16
위의 예시 코드처럼 형변환을 통해서 여러가지 자료형을 주고 받거나 연산할 수 있지만, 주의할 점이 하나 있다.
바로 옵셔널 타입의 변수는 바로 형변환을 할 수 없다는 것이다.
(옵셔널에 대한 추가 설명은 본문 아래에 있음.)
왜냐하면, 옵셔널은 nil 값을 가질 가능성을 가지고 있기 때문이다.
nil을 형변환 하려고 하면 에러가 발생할 것이기 때문에 컴파일 단계에서 미리 예방을 해주는 것인데,
사실 위의 예시 코드의 형변환 방식은 메모리에 새로운 인스턴스를 만들어서 바뀐 Type의 값을 저장해주는 방식이다.
따라서, Double(인수) 이라는 생성자에 nil을 전달하면 에러가 날 수 밖에 없을 것이다.
var integer_: Int = 10
// integer_ 의 값인 10을 인자로 하여, 새로운 Double 타입의 변수(인스턴스)를 메모리에 생성한다.
var double_: Double = Double(integer_)
위처럼 integer_ 라는 변수가 Int 타입으로, 10 이라는 primitive 값을 할당받고 있다면 문제없이 형변환이 이루어진다.
하지만 아래처럼, 변수가 옵셔널 타입이면 컴파일 단계에서 에러를 발생시킨다.
var integer_: Int? = 10
var double_: Double = Double(integer_) // 에러 발생.
// 에러 메시지:
// Value of optional type 'Int?' must be unwrapped to a value of type 'Int'
// 'Int?' 타입의 변수는 반드시 'Int'로 언래핑을 해주어야 합니다.
그리고 String 타입에 대한 형변환에 대해서는 특이사항이 더 있다.
먼저 코드부터 보자면,
var strValue: String = "10"
var integer_: Int = Int(strValue) // 에러 발생.
위의 코드는 에러가 발생한다.
에러가 발생하는 이유는 String 타입의 변수는 숫자가 아닌 값을 갖고 있을수도 있기 때문이다.
변수 strValue에 들어있는 "10"은 정상적으로 형변환이 이루어지기는 하겠지만, 알파벳이나 한글, 특수문자 등의 값들이 함께 포함되어 있을 가능성도 있다.
그래서 String 타입의 변수는 형변환을 할 때, 무조건 옵셔널 타입으로 값을 반환한다.
그리고 만약 다른 문자때문에 형변환에 실패했다면 nil을 반환한다.
var strValue: String = "10"
var integer_: Int? = Int(strValue) // 정상 동작.
print(integer_) // 출력: Optional(10)
strValue = "10원"
integer_ = Int(strValue)
print(integer_) // 출력: nil
📎 튜플(Tuples) 선언 / 사용 방법
튜플(Tuples)은 다른 언어에서는 딕셔너리 또는 맵이라는 이름으로 불리는 자료 구조와 거의 같은 개념이다.
// 선언
var title = ("제목 이미지", "/img/title.png")
// 사용 방법
title.0 // "제목 이미지"
title.1 // "/img/title.png"
위처럼 선언하여 index로 접근하도록 사용할 수도 있지만, 아래처럼 접근할 수 있는 이름을 붙여서 사용할 수도 있다.
// 선언
var title = (content: "제목 이미지", path: "/img/title.png")
// 사용 방법
title.content // "제목 이미지"
title.path // "/img/title.png"
그리고 변수/상수와 마찬가지로 타입 어노테이션을 사용할 수도 있다.
// 선언
var title: (content: String, path: String) = ("제목 이미지", "/img/title.png")
// 사용 방법은 동일하다.
🧐 [옵셔널(Optional)]
스위프트에서는 옵셔널이 아닌 변수에는 nil을 할당할 수 없다.
따라서, 변수에 들어올 값이 nil 일 수도 있을 때 사용한다.
// 선언: `?`를 붙인다.
var age: Int? = 0
📎 언래핑(Unwrapping) / 닐-코알레싱(Nil-Coalescing)
옵셔널로 선언된 변수는,
사용할 때(연산할 때) 반드시 언래핑(Unwrapping) 또는 닐-코알레싱(Nil-Coalescing) (콜레싱??)을 해줘야 한다.
- 강제 언래핑(Force Unwrapping) : 변수에 값이 확실히 들어있다는 보장이 될 때만 사용하는 것이 좋다.
- 닐-코알레싱(Nil-Coalescing) : 변수에 nil이 할당되어 있다면, 지정해놓은 값으로 치환해서 반환해준다.
이는 옵셔널 변수에 nil이 할당되어 있을 경우 crash 발생을 방지하기 위함으로, 다음과 같이 사용한다.
// 옵셔널 변수 age 선언.
var age: Int? = 0
// 에러 발생하는 코드
var sum = age + 10 // age 변수가 옵셔널이기 때문에, 컴파일 단계에서 에러 발생함.
// 강제 언래핑(Force Unwrapping)
var sum = age! + 10 // crash가 발생하여 앱이 종료될 위험이 있음.
// 닐-코알레싱(Nil-Coalescing)
var sum = (age ?? 0) + 10 // age가 nil이면 0을 반환한다.
📎 옵셔널 바인딩(Optional binding)과 guard-else 문
코알레싱과 마찬가지로, 옵셔널을 안전하게 처리하는 방법 중 하나이다.
// if let 또는 if var
if let hasAge: age { // age가 nil이 아니라면, 해당 값을 hasAge 변수에 할당해줌.
print(hasAge)
} else {
print("age 변수에 nil이 할당되어 있음.")
}
guard-else 문법은 옵셔널 바인딩에 실패했을 때, 일종의 예외처리를 위해 사용한다.
class Sample{
guard let hasAge = age else {
return // 바인딩에 실패했을 경우에 else 블록을 실행한다.
}
print(hasAge)
}
- else 블록에서는 반드시 return으로 해당 블록을 종료시켜야 한다.
- guard문에서 바인딩에 실패하면, 그 아래의 코드들은 실행되지 않는다.
- 바인딩에 성공했다면, 바인딩된 변수(hasAge)는 함수(또는 클래스)의 스코프 내에서 일반 변수 타입으로 사용할 수 있다.
'iOS(macOS) > Swift' 카테고리의 다른 글
[Swift/문법] Closure (클로저) (0) | 2022.08.07 |
---|---|
[Swift/문법] 제어문(Control flow), Function (0) | 2022.08.04 |
[Swift/문법] Collection(Array, Set, Dictionary) (0) | 2022.07.28 |
[Xcode] 파일 확장자 표시하기 (0) | 2022.07.13 |
[Xcode] 스토리 보드 - 첫 화면 설정하기 (Main interface) (0) | 2022.07.13 |