이 글은 https://bbiguduk.gitbook.io/swift 에 나오는 스위프트 문법을 공부하면서 새롭게 알게 된 지식들을 정리한 포스팅입니다.
let
키워드로 상수로 설정하는 것이 좋다.let
으로 설정하고 바꾸어야 할 때 로 var
로 바꾸기를 습관화하자.var x = 0.0, y = 0.0, z = 0.0
var red, green, blue: Double
UInt8
, Int8
등의 타입명을 가진다.min
과 max
프로퍼티를 가진다.let minValUInt8 = UInt8.min // 0
let maxValUInt8 = UInt8.max // 255
let minValInt8 = Int8.min // -128
let maxValInt8 = Int8.max // 127
Int.max == Int64.max
)UInt
는 왠만하면 unsigned 정수값이 필요한 경우에만 사용하도록 하자. (→ 타입 추론에 용이)Float
은 32-bit 부동 소수점, Double
은 64-bit 부동 소수점 숫자를 표기한다.Float
은 최소 6자리, Double
은 최소 15자리의 정확성을 가진다.max
와 min
프로퍼티를 가지지 않는다.Double
타입으로 유추된다.let pi = 3 + 0.14159 // Double.Type
let typeAnnotation: String // 가능
let typeInferece = "" // 가능
let typeInferece // 불가능
let wantToBeFloat = 10.0
type(of: wantToBeFloat) // Double
let wantToBeCharacter = "C"
type(of: wantToBeCharacter) // String
let decimalInteger = 17
let binaryInteger = 0b10001
let octalInteger = 0o21
let hexadecimalInteger = 0x11
1.25e2
는 1.25 x 10², 또는 125.0
, 1.25e-2
는 1.25 x 10⁻² , 또는 0.0125
let paddedDouble = 000123.456
let oneMillion = 1_000_000.000_000
UInt
타입으로 음수를 저장하거나, max, min 값을 넘기는 경우가 대표적이다.정수와 부동 소수점 변수와 상수 간의 타입의 변환은 명시적이어야 한다.
리터럴 값은 명시적인 타입이 없기 때문에 특별히 형변환이 필요하지 않다.
// 변수/상수
let three = 3
let point = 0.14159
let pi = Double(three) + point
// 리터럴
let pi = 3 + 0.14159
부동 소수점 값을 정수 타입으로 변환하면(Int(pi)
), 소수점 아래는 버린다.
특정 크기의 데이터로 작업할 때 유용하다.
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min // 0
모든 타입이 가능하며, 서로 같은 타입일 필요도 없고 원하는 만큼 타입을 포함할 수 있다.
튜플의 내용을 별도의 상수로 분해(Decompose)할 수 있다.
let http404Error = (404, "Not Found") // (Int, String)
let (statusCode, statusMessage) = http404Error
let (statusCodeOnly, _) = http404Error
http404Error.0 // 404
http404Error.1 // Not Found
let http200Status = (statusCode: 200, description: "OK")
http200Status.statusCode // 200
http200Status.description // "OK"
nil
예로, Int()
는 String
타입을 Int
타입으로 반환하지만 문자가 포함된 경우는 불가능하다.
nil
반환 가능성이 있기 때문에, Optional
값을 반환한다. (즉 Int
이거나, 아무런 값도 없다.)
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber) // Optional(123)
let convertedNumber: Int = Int(possibleNumber) // 에러 발생
let convertedNumber: Int? = Int(possibleNumber) // 사실 위는 타입추론 된 것이다
Optional
타입 변수에만 nil
을 할당할 수 있다.var serverResponseCode: Int? = 404
serverResponseCode = nil // Int 타입으로 바꾸면 에러 발생
Optional
변수는 nil
이 자동할당 된다.var optionalString: String? // nil
nil
은 Object-C의 nil과 다르다.값이 반드시 들어있을 경우에만 사용해야 하므로 if 구문 스코프 내에서 쓰는 것이 좋다.
if convertedNumber != nil {
print("\(convertedNumber!)")
}
**Optional
변수(우측항)가 값을 포함하고 있는지 확인하여 임시 상수나 변수(좌측항)**으로 사용한다.일반적으로 사용하는 let
뿐 아니라 var
도 사용 가능하다. (스코프 내에서만 적용됨)
let optionalString: String? = "Not Optional"
if var strValue = optionalString {
print(strValue) // Not Optional
} else {
print("nilkaboo")
}
let myNumber = Int("123")
if let myNumber = myNumber {
print(myNumber) // 123
}
print(myNumber) // Optional(123)
언래핑할 상수/변수의 이름만 작성하면 암시적으로 같은 이름의 언래핑된 상수가 만들어진다.
if let myNumber {
print(myNumber)
}
nil
값이 존재하거나 조건식이 false
이면 전체 구문이 false
가 된다.
if let firstNumber = Int("27") {
if let secondNumber = Int("72") {
if firstNumber < secondNumber && firstNumber + secondNumber < 100 {
print(firstNumber + secondNumber) // 99
}
}
}
if let firstNumber = Int("27"),
let secondNumber = Int("72"),
firstNumber < secondNumber,
firstNumber + secondNumber < 100 {
print(firstNumber + secondNumber) // 99
}
Optional
상수/변수에 특정 타입의 값을 지정했을 경우 매번 언래핑하여 사용하는 것은 비효율적.명시적으로 옵셔널이 아닌 타입의 상수/변수에 담으려고 하면 강제로 언래핑된다.
옵셔널 타입 상수/변수에 담으면 강제 언래핑되지 않고 옵셔널 타입이 된다.
let possibleString: String? = "optional string"
let forcedString: String = possibleString!
let assumedString: String! = "implicitly unwrapped optional string"
let implicitString: String = assumedString // 이때 강제 언래핑
let optionalString: String = assumedString // Optional("...")
nil
값이 들어 있을 경우 접근하면 (컴파일 에러가 아닌) 런타임 에러가 발생한다.nil
이 될 가능성이 조금이라도 있다면 IUO 사용하면 안 된다.if
구문에서 nil
체크도, 옵셔널 바인딩도 가능하다.nil
체크 시 비교연산 하면서 옵셔널로 확정되어 if
스코프 안에서는 다시 옵셔널로 래핑된다.
if assumedString != nil {
print(assumedString!) // 언래핑 안 하면 Optional("...")로 나온다.
}
if let definiteString = assumedString {
print(definiteString)
}
throws
키워드를 포함해야 한다.그 함수를 호출할 때는 표현식 앞에 try
키워드가 있어야 한다.
func canThrowAnError() throws {
// ...
}
do {
try canThrowAnError()
// no error zone
} catch {
// error thrown
}