*Swift Language Guide를 우리말로 풀이하고 편집한 것이다. The Basics 섹션의 내용을 담고 있다.
변수와 상수
var variableName = 42
let constantName = 12
var variableName: Type
let constantName: Type
변수/상수 선언하기
변수는 var, 상수는 let이라는 키워드로 선언한다. `var x = 0.0, y = 0.0, z = 0.0` 같이 여러 개의 변수나 상수를 쉼표로 구분하여 동시에 선언할 수도 있다.
변수/상수의 이름
유니코드 문자를 비롯한 거의 모든 문자를 변수/상수의 이름으로 사용할 수 있다. 이름은 카멜케이스 형식으로 표현하며, 중간에 숫자를 포함할 수 있지만 숫자로 시작해서는 안 된다. 예약어(Reserved keyword)와 동일한 이름의 경우(예: class), 백틱으로 감싸 사용할 수는 있으나 권장되지 않는다.
변하지 않을 값은 상수로 선언한다
여기서 변하지 않을 값이란 프로그램과 비즈니스 정책 측면에서 고정하여 사용할 값을 의미한다. 예를 들어 로그인 시도를 최대 10회까지 허용한다는 정책에 따라 코드를 작성하는 경우, 최대 로그인 시도 횟수 10은 변하지 않을 값이기에 상수로 선언하고 사용자의 현재 로그인 시도 횟수는 누적하여 계산해야 하는 것이기에 변수로 선언한다. 변하지 않을 값을 상수로 선언하면 작업 과정에서 발생하는 오류를 방지할 수 있다.
변수/상수 출력하기
`print(_:separator:terminator:)` 함수를 이용하여 변수/상수의 값을 출력할 수 있다. `separator`와 `terminator` 매개 변수는 생략이 가능하며 생략할 경우 두 매개 변수의 기본값이 적용된다. 기본값으로 print 함수는 값을 한 번 출력할 때마다 줄 바꿈을 하는데, 줄 바꿈 없이 출력을 하려면 terminator 매개 변수의 인수로 빈 문자열을 전달하면 된다. `print(someValue, terminator: "")`와 같은 형태로 작성할 수 있다. 또한 변수/상수의 이름을 괄호로 감싸고 그 앞에 백슬래시를 붙여 문자열 안에 삽입할 수 있다. `print("Today is \(currentDate)")`과 같은 형태가 된다.
변수/상수의 타입 주석
변수/상수를 선언할 때 타입 주석(Type annotation; 타입 어노테이션)을 추가해 해당 변수/상수가 저장할 수 있는 데이터 타입을 명시할 수 있다. `var variableName: Type`과 같이 변수/상수의 이름 뒤에 콜론(:)을 붙이고 해당하는 데이터 타입을 입력하면 된다. `var x, y, z: Int` 같이 여러 개의 변수나 상수를 쉼표로 구분하여 동시에 타입 주석을 추가할 수도 있다. 변수/상수를 선언하면서 타입 주석을 동시에 추가하는 경우, `var x: Int = 42`와 같은 형태가 된다.
타입 안전성과 타입 추론
타입 안전성을 중요시하는 Swift는 코드를 컴파일할 때 타입을 검사하고, 타입의 짝이 맞지 않는 경우(예: String이 필요한 자리에 Int를 사용한 경우) 오류를 표시한다. 이러한 타입 검사는 개발 과정에서 오류를 최대한 빨리 찾아낼 수 있게 해준다. 변수/상수를 선언할 때 데이터 타입도 함께 선언할 수 있지만 필수는 아니다. Swift가 선언된 변수/상수의 초기값(리터럴 값)을 토대로 데이터 타입을 알아서 인식하기 때문이다. 이를 타입 추론(Type inference)이라고 한다. 타입 추론은 코드를 보다 간결하고 읽기 쉽게 만든다. 데이터 타입이 추론된 이후에는 변수/상수에 해당 데이터 타입만 담을 수 있다. 초기값으로 소수를 입력한 경우, 소수점 자릿수에 관계없이 모두 Float(부동 소수점)이 아닌 Double(배정밀도 부동 소수점)로 인식된다. `let anotherPi = 3 + 0.14159`와 같이 정수와 소수를 함께 입력한 경우에도 데이터 타입은 Double로 인식된다. option 키를 길게 누른 상태에서 변수/상수 이름을 클릭하면 추론된 데이터 타입을 확인할 수 있다.
주석
// 한 줄 주석
/* 여러 줄
주석 */
한 줄 주석은 슬래시 두 개(//)를 맨 앞에 입력하여 표기하고, 여러 줄 주석은 슬래시와 별표로(/* */) 내용을 감싸 표기한다. 여러 줄 주석 안에 또 다른 주석을 중첩할 수도 있다. Swift 컴파일러는 주석을 코드로 인식하지 않는다.
세미콜론
다른 프로그래밍 언어와 달리 Swift에서는 코드 끝에 세미콜론(;)을 입력할 필요가 없다.
다만 `let cat = "🐱"; print(cat)`과 같이 여러 개의 코드를 한 줄에 작성할 때에는 세미콜론으로 구분을 해야 한다.
정수
42나 -23처럼 소수부가 없는 수를 의미하는 정수는 부호 있는 정수(Signed integer)와 부호 없는 정수(Unsigned integer)로 나뉜다. 부호 있는 정수는 음수, 양수, 영을 나타내고 부호 없는 정수는 양수와 영을 나타낸다. Swift는 정수를 8비트, 16비트, 32비트, 64비트 형태로 지원하며 각각 Int8/UInt8, Int16/UInt16, Int32/UInt32, Int64/UInt64라는 데이터 타입을 가진다. 다른 모든 데이터 타입처럼 정수의 타입 이름도 대문자로 시작한다.
정수의 최솟값과 최댓값
min과 max 속성을 이용하여 각 정수 타입의 최솟값과 최댓값에 접근할 수 있다.
let minValue = UInt8.min // minValue의 값은 0이고 타입은 UInt8이다
let maxValue = UInt8.max // maxValue의 값은 255이고 타입은 UInt8이다
특별한 이유가 없다면 Int 타입을 사용한다
대부분의 경우, 정수의 크기를 지정할 필요 없이 `Int`라는 데이터 타입을 사용하면 된다. Int는 현재 플랫폼의 기본 워드 크기와 동일한 크기를 갖는다. 32비트 플랫폼의 경우 Int는 Int32와 동일한 크기를 갖고, 64비트 플랫폼의 경우 Int는 Int64와 동일한 크기를 가진다. 특정한 정수 크기를 지정해야 하는 것이 아니라면 코드의 일관성과 호환성 측면에서도 Int를 사용하는 것이 낫다. 32비트 플랫폼의 Int만 해도 -2,147,483,648과 2,147,483,647 사이의 값을 저장할 수 있기 때문에 대부분의 정수 범위를 처리하기에 충분하다.
부호 없는 정수에는 UInt를 사용할 수도 있긴 하지만
Swift는 부호 없는 정수 타입으로 `UInt`를 지원하며 UInt도 현재 플랫폼의 기본 워드 크기와 동일한 크기를 갖는다. 그러나 현재 플랫폼의 기본 워드 크기와 동일한 크기의 부호 없는 정수를 반드시 사용해야 하는 경우가 아니라면 (저장할 값이 음수가 아닌 것이 확실할지라도) Int를 사용하는 것이 좋다. 코드 호환성을 높이고 여러 숫자 타입을 전환해야 할 필요성을 줄이기 위해서이다.
별도로 지정하지 않으면 모두 Int로 인식된다
var number = 1 // number의 타입은 Int이다
앞서 말한 타입 추론 기능 때문이다.
부동 소수점 숫자
부동 소수점 숫자(Floating-point number)는 0.1이나 -273.15 같이 소수부가 있는 숫자로, 정수보다 더 넓은 범위의 수를 나타낼 수 있다. 부동 소수점 숫자의 타입은 소수 자릿수를 15개까지 표시할 수 있는(64비트) Double과 6개까지 표시할 수 있는(32비트) Float으로 나뉜다. 두 타입을 모두 사용할 수 있는 상황이라면 Double을 사용하는 것이 낫다. 타입 추론 시에도 모든 소수는 Double로 인식된다.
숫자 타입 변환
Swift에서 숫자는 Int, Float, Double 등의 데이터 타입을 가지는데, 특정한 타입의 숫자를 다른 타입의 숫자로 변환할 수 있다. 이를 타입 변환(Type conversion)이라 한다.
정수 변환
정수형 변수/상수에 저장할 수 있는 숫자의 범위는 타입별로 다르다. 일례로 `Int8` 변수/상수는 -128과 127 사이의 수를 저장할 수 있고, UInt8 변수/상수는 0과 255 사이의 수를 저장할 수 있다. 타입의 범위에 맞지 않는 수를 할당하면 컴파일 시 오류가 발생한다.
let cannotBeNegative: UInt8 = -1
// UInt8은 음수를 저장할 수 없기 때문에 오류가 발생한다.
let tooBig: Int8 = Int8.max + 1
// Int8은 해당 타입의 최댓값보다 큰 수를 저장할 수 없기 때문에 오류가 발생한다.
타입이 다른 변수/상수의 값을 결합하기 위해서는 타입 변환을 해야 한다. 타입을 변환하는 코드는 `NewType(initialValue)`와 같다. 기존 변수/상수를 괄호로 감싸고 그 앞에 변환하고자 하는 새로운 타입 이름을 입력하면 된다. 아래의 예시에서는 타입이 UInt8인 상수 one을 UInt16 타입으로 변환하기 위해 UInt16(one)이라는 코드를 작성했다.
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
// 타입이 UInt16인 두 상수를 결합했기 때문에 twoThousandAndOne의 타입은 UInt16으로 추론된다.
위 예시에서 UInt8이라는 타입이 UInt16이라는 타입으로 변환될 수 있는 이유는 UInt16 타입이 UInt8 값을 받아들이는 이니셜라이저(Initializer)를 가지고 있기 때문이다. `NewType(initialValue)`는 이러한 이니셜라이저를 호출하는 코드이다. UInt16의 이니셜라이저를 호출한다는 것은 기존 타입의 값으로 새로운 UInt16 타입을 초기화한다는 의미이다. 여기서 initialValue 자리에 아무 타입이나 다 넣을 수 있는 것은 아니다. 새롭게 변환하고자 하는 타입이 기존 타입에 대한 이니셜라이저를 제공하는 경우에만 가능하다.
정수-부동 소수점 숫자 변환
정수와 부동 소수점 숫자 사이의 변환도 NewType(initialValue)와 같이 새로운 타입을 초기화하는 방식으로 이루어진다. 부동 소수점 숫자를 정수로 변환하면 소수점 이하가 잘린다(예: 4.75를 정수로 변환하면 4가 됨).
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// 상수 pi의 값은 3.14159이고 타입은 Double로 추론된다
let integerPi = Int(pi)
// 상수 integerPi의 값은 3이고 타입은 Int로 추론된다
숫자 변수/상수를 결합하는 것과 숫자 리터럴을 결합하는 것에는 차이가 있다.
let pi = 3 + 0.14159
변수/상수에 할당되지 않은 리터럴 값은 데이터 타입이 없기 때문에 타입 변환 없이도 결합이 가능하다. 위 예시에서 `3 + 0.14159`라는 수식은 pi라는 상수에 할당되기 전에 계산되며 컴파일러는 계산된 최종값(3.14159)을 토대로 Double 타입을 추론한다.
타입 별칭
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min
// UInt16 타입의 최솟값(UInt16.min)은 0이기 때문에 AudioSample.min 역시 0이다
타입 별칭(타입 앨리어스, Type Alias)은 기존 타입 이름 대신에 사용하는 사용자 지정 이름이다. typealias 키워드로 타입 별칭을 지정할 수 있다. 타입 별칭은 특정한 의미를 담은 이름을 사용하는 것이 단순한 타입 이름보다 코드 맥락을 이해하는 데 더 유용할 때 사용한다. 지정한 타입 별칭은 해당 타입 이름을 사용할 수 있는 모든 곳에 대신하여 사용할 수 있다.
불리언(부울)
Swift의 불리언(Boolean) 타입은 `Bool`이며, 값으로 true 또는 false를 가질 수 있다.
let matchaIsGreat = true
let mintChocoIsDelicious = false
true와 false라는 불리언 리터럴 값으로 변수/상수를 초기화하면 데이터 타입이 Bool로 추론되기 때문에, 별도로 타입을 지정할 필요는 없다. 불리언 값은 if-else 같은 조건문에 활용된다.
if mintChocoIsGreat {
print("Mmm, tasty mint choco icecream!")
} else {
print("Eww, mint choco is awful.")
}
if 조건문에서 if 조건절의 명령은 if 조건을 검사한 값이 참일 때 실행되고, else 조건절의 명령은 if 조건을 검사한 값이 거짓일 때 실행된다. if 조건에 `==`, `!=` 등의 연산자를 사용하지 않고 위 예시와 같이 변수/상수만 표시하는 경우, if 조건절에서 해당 변수/상수의 값이 참인지 아닌지 검사한다. 여기서 mintChocoIsGreat의 값은 false이기 때문에 첫 번째 조건(if mintChocoIsGreat == true)를 만족하지 않고, else 조건을 충족하여 "Eww, mint choco is awful."를 출력한다.
if 조건문을 비롯한 조건문에서 조건의 값은 언제나 불리언 타입이어야 한다.
let i = 1
if i {
// i의 데이터 타입은 Int이기 때문에 컴파일 시 오류가 발생한다.
}
let j = 2
if j != 1 {
// j != 1은 값이 true인 불리언 타입이므로 이 명령은 성공적으로 실행된다.
}
튜플
튜플(Tuple)은 여러 개의 값을 하나의 복합 값으로 묶어 준다. 튜플의 요소는 모든 데이터 타입을 가질 수 있으며 각 요소의 데이터 타입이 동일할 필요도 없다. 튜플로 묶을 수 있는 요소의 개수에도 제한이 없다. 튜플의 기본 형태는 `let constantName = (value1, value2, ... )`이고 튜플의 요소(값)를 사용할 수 있는 방법에는 세 가지가 있다.
튜플의 요소를 상수나 변수로 분해하여 사용하기
튜플을 `let (constantName1, constantName2) = tupleName`과 같은 형태로 분해하여 각 요소를 상수나 변수에 할당할 수 있다.
let http404Error = (404, "Not Found") // 튜플 정의. 타입은 (Int, String).
let (statusCode, statusMessage) = http404Error // 튜플 요소를 상수로 분해
print(statusCode) // 상수를 이용하여 튜플 요소 출력
print(statusMessage)
특정 요소만 할당하는 것도 가능하다. 원하는 요소 위치에 상수/변수 이름을 입력하고, 나머지 요소의 자리에는 밑줄(_)을 입력하면 된다.
let http404Error = (404, "Not Found")
let (justTheStatusCode, _) = http404Error
print(justTheStatusCode)
인덱스 번호로 튜플의 요소를 가져오기
0부터 시작하는 인덱스 번호로 튜플의 요소를 가져올 수 있다.
let http404Error = (404, "Not Found")
print(http404Error.1)
튜플 요소에 이름을 지정하여 사용하기
`let constantName = (valueName1: value1, valueName2: value2)`와 같은 형태로 튜플을 정의할 때 각 요소의 이름을 지정할 수 있으며, `constantName.valueName1`과 같이 점 표기법으로 각 요소 값에 접근할 수 있다.
let http404Status = (statusCode: 404, description: "Not Found")
print(http404Status.statusCode)
튜플은 어디에 쓰이나
튜플은 함수의 반환 값으로 쓰기에 유용하다. 튜플을 이용하여 여러 가지 타입의 값을 반환할 경우, 한 가지 타입의 값만 반환하는 것보다 더 많은 정보를 전달할 수 있다. 튜플은 서로 관련이 있는 단순한 형태의 값을 전달할 때 유용하며, 복잡한 데이터 구조를 생성해야 하는 경우에는 튜플 대신 구조체나 클래스를 사용하는 것이 낫다.
옵셔널
옵셔널(Optional)은 값이 존재하지 않을 수도 있을 때 사용한다. 옵셔널은 두 가지 가능성을 내포하고 있는데, 하나는 값이 존재하며 옵셔널을 해제하여 그 값에 접근할 수 있는 것이고 다른 하나는 값이 아예 없는 것이다.
타입 변환 기능을 이용하여 `String` 값을 `Int` 값으로 변환하는 경우를 예로 들어보자. '123'이라는 String 값은 숫자로 변환이 가능하지만, 'Hello, World'라는 String 값은 문자로 이루어져 있어 숫자 변환이 불가능하다. 이처럼 타입 변환에 실패할 가능성도 있기 때문에 String 값을 Int 값으로 변환하면 그 타입은 옵셔널 Int, 즉 `Int?`가 된다.
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber의 타입은 옵셔널 Int인 Int?로 추론된다.
`Int?`는 그 값이 정수일 수도 있고 값이 아예 없을 수도 있다는 의미이다. 이때 다른 타입의 값은 포함되지 않으며 오직 명시된 타입의 값이 있거나 아무 것도 없는 상태만 가능하다.
let possibleNumber = "Hello"
let convertedNumber = Int(possibleNumber)
print(convertedNumber)
// 문자를 숫자로 변환할 수 없기 때문에 값은 존재하지 않는 상태가 되고 아무것도 출력되지 않는다.
nil(닐)
특정한 조건 하에서 상수나 변수가 아무 값도 담고 있지 않아야 하는 경우, 해당 상수/변수의 타입을 옵셔널로 선언한다. 타입이 옵셔널인 변수에 `nil` 값을 할당하면 값이 없는 상태를 만들 수 있다. `nil`은 타입이 옵셔널인 경우에만 할당이 가능하다.
var serverResponseCode: Int? = 404
// 타입을 옵셔널 Int로 선언한다. 현재 serverResponseCode의 값은 404이다.
serverResponseCode = nil
// serverResponseCode는 이제 어떠한 값도 담고 있지 않다.
기본값을 할당하지 않고 옵셔널 타입만 선언하는 경우, 해당 변수의 값은 자동적으로 `nil`이 된다.
var surveyAnswer: String?
// surveyAnswer의 값은 자동으로 nil이 된다
Swift의 `nil`은 Objective-C의 `nil`과는 다르다. Objective-C에서 `nil`은 존재하지 않는 객체의 포인터지만, Swift의 `nil`은 포인터가 아니며 특정한 타입의 값이 없음을 나타낸다. Swift에서는 모든 옵셔널 타입을 `nil`로 설정할 수 있다.
If 문과 강제 해제
If 문을 이용하여 옵셔널의 값이 있는지 없는지 확인할 수 있다. '같음' 연산자(==)나 '같지 않음' 연산자(!=)를 이용하여 옵셔널의 값을 nil 값과 비교해주면 된다. 옵셔널에 값이 있다는 것은 옵셔널이 nil이 아님을 의미한다.
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// convertedNumber의 값이 nil이 아닌 경우 명시된 문자열을 출력하라는 코드이다
옵셔널에 값이 있는 경우, 옵셔널 이름 끝에 느낌표(!)를 추가하여 내부 값에 접근할 수 있다. 이 느낌표는 '이 옵셔널에는 값이 확실히 있으니 그 값을 사용한다'는 의미를 담고 있다. 이렇게 느낌표를 추가하여 옵셔널의 값을 가져오는 것을 강제 해제(forced unwrapping)라 한다.
convertedNumber: Int? = 123
if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// 옵셔널 정수인 convertedNumber의 값을 사용하기 위해 느낌표를 붙여 강제 해제했다
옵셔널 값이 존재하지 않는 상태에서 느낌표를 붙여 강제 해제하면 런타임 오류가 발생한다. 존재하지 않는 것을 실행하려 했기 때문이다. 이를 방지하기 위해 옵셔널을 강제 해제하기 전에는 반드시 값이 nil이 아님을 확인해야 한다.
옵셔널 바인딩
옵셔널 바인딩(Optional binding)을 통해 옵셔널에 값이 있는지 확인하고, 값이 있을 경우 해당 값을 상수나 변수에 할당하여 사용할 수 있다. if 문이나 while 문으로 옵셔널 값을 확인하고 그 값을 상수나 변수에 담는 과정이 하나의 동작으로 이루어진다.
if 문을 이용한 옵셔널 바인딩의 형식은 다음과 같다. `someOptional`의 값이 nil이 아닌 경우(값이 있는 경우), 그 값을 `constantName`에 할당하여 명시된 코드를 실행한다는 의미를 담고 있다. 옵셔널의 값을 상수에 담아 사용하려면 `if let` 키워드를 쓰고, 변수에 담아 사용하려면 `if var` 키워드를 쓴다.
if let constantName = someOptional {
statements
}
이 형식을 실제 코드에 적용하면 다음과 같다.
let possibleNumber = 123
if let actualNumber = possibleNumber {
print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
// possibleNumber의 값이 nil이 아닌 경우 그 값으로 actualNumber라는 상수를 선언하고 코드를 실행한다
} else {
print("The string \"\(possibleNumber)\" could not be converted to an integer")
// possibleNumber의 값이 nil인 경우 새로운 상수를 선언하지 않고 이 코드를 실행한다
}
강제 해제 방식으로 옵셔널 값을 활용하기 위해서는 옵셔널에 접미사로 느낌표를 붙여야 하지만, 옵셔널 바인딩을 활용할 경우 느낌표를 붙이지 않고 바로 사용할 수 있다. 옵셔널의 값이 nil이 아님을 확인하는 과정을 이미 거쳤고, 그렇게 확인된 값이 새로운 변수/상수에 할당되었기 때문이다.
여러 개의 옵셔널 바인딩과 불리언 조건을 쉼표로 구분하여 동시에 지정할 수도 있다. 이때 옵셔널 바인딩의 경우, 각 상수/변수 앞에 let/var 키워드를 입력해야 한다. 제시된 모든 옵셔널 바인딩의 값 중 nil 값이 하나라도 있거나 불리언 값이 false이면 전체 if 조건은 false로 간주된다. 이를 코드로 나타내면 다음과 같다.
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) is less than \(secondNumber) < 100")
}
// "4 < 42 < 100" 출력
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
}
}
// "4 < 42 < 100" 출력
암시적으로 해제된 옵셔널
옵셔널에 값이 언제나 존재할 것이 확실한 경우, 옵셔널을 정의할 때 타입 뒤에 느낌표를 붙여 암시적으로 해제된 옵셔널(Implicitly unwrapped optional)을 만들 수 있다. 옵셔널의 이름 뒤에 느낌표를 붙여 해제하는 일반적인 방식과 다르게 암시적으로 해제된 옵셔널의 경우, 타입 뒤에 느낌표를 붙인다.
let possibleString: String? = "An optional string."
let forcedString: String = possibleString!
// possibleString은 일반적인 옵셔널이기 때문에 타입이 String인 상수에 할당하기 위해서는 느낌표를 붙여 해제해야 한다
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString
// assumedString은 암시적으로 해제된 옵셔널이기 때문에 타입이 String인 implicitString에 바로 할당할 수 있다
암시적으로 해제된 옵셔널은 일반적인 상황에서는 옵셔널로 기능하나 옵셔널을 사용할 수 없는 경우에는 자동으로 강제 해제된다. nil 값을 확인하고 옵셔널을 해제하는 과정은 필요하지 않다.
let assumedString: String! = "An implicitly unwrapped optional string."
let optionalString = assumedString
// optionalString의 타입이 명시되지 않았기 때문에 assumedString이 강제 해제되지 않고 옵셔널로 할당된다
암시적으로 해제된 옵셔널에도 if 문을 이용한 nil 값 검사와 옵셔널 바인딩을 사용할 수는 있지만, 애초에 nil 값 검사가 필요한 경우라면 일반적인 옵셔널을 사용하는 것이 낫다. 값이 nil이 될 수 있는 가능성이 조금이라도 있다면 암시적으로 해제된 옵셔널을 사용해선 안 된다. 암시적으로 해제된 옵셔널의 값이 nil인 상태에서 그 값을 사용하려고 하면 런타임 오류가 발생한다.
'Swift 언어 가이드' 카테고리의 다른 글
Swift 언어 가이드 - 문자와 문자열 (0) | 2020.05.05 |
---|---|
Swift 언어 가이드 - 기본 연산자 (0) | 2020.04.14 |