본문 바로가기

iOS/Swift

Swift 공식 문서 1. The Basics

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics

 

Documentation

 

docs.swift.org

Swift 공식 문서 보면서 내 맘대로 정리


Constant and Variables ( 상수와 변수)

  • 상수, 변수를 한 줄에 선언할 수 있다.
var x = 0.0, y = 0.0, z = 0.0
var red, green, blue : Double
  • 변수와 상수의 이름은 유니코드로 선언할 수 있다.
let 😍 = "love"
  • print 함수는 separator, terminator를 갖고 이들은 default 값을 다음과 같이 갖는다
public func print(_ items: Any..., separator: String = " ", terminator: String = "\\n")

Integers(정수)

  • Swift는 8,16,32,64 비트 형식의 부호 있는 정수와 부호 없는 정수를 제공한다.
  • 부호 없는 정수는 UInt8과 같이 앞에 U(Unsigned)가 붙는다.
  • 각 정수값의 최대, 최소 값은 min, max 프로퍼티로 접근할 수 있다. ( UInt8.min , UInt8.max )
  • 일반적으로 사용할 때 그냥 Int 형을 사용한다면 32비트 플랫폼 에서는 Int32형 64 비트 플랫폼 에서는 Int64형을 사용한다.
  • Int32도 2,147,483,648 ~ 2,147,483,647 값을 저장 하므로 충분히 크다. (-2^32 ~ 2^32 -1)

Floating-Point Numbers ( 부동소수점 )

  • Double은 64비트 부동소수점 : 정밀도는 15자리 소수점
    • Float보다 정밀도가 높다
  • Float은 32비트 부동소수점 : 정밀도는 6자리 소수점
    • Double 보다 메모리 사용량 더 낮다.
  • Swift에서 부동소수점을 추론할 때는 항상 Double로 추론한다.
let number = 1.0
print(type(of: number)) // Double
  • 정수와 부동소수점 사이의 변환은 명시적으로 작성해야 한다.
  • 특정 숫자 자료형과 literal number간의 연산은 literal number의 자료형을 암시적으로 컴파일러가 알맞게 추론 해준다.
let three = 3 
let pointOneFourOneFiveNine = 0.14159 

let pi = Double(three) + pointOneFourOneFiveNine

let pi2 = 3 + pointOneFourOneFiveNine

Type Aliases

  • 기존 타입을 다른 이름으로 선언할 수 있다.
typealias AudioSample = UInt6

//UInt6 대신 AudioSample을 사용한다.
var a : AudioSample = 1

Tuples

  • Tuple 내의 값은 모든 자료형이 가능하고 여러 개의 자료형을 함께 사용할 수 있다.
  • 튜플의 값들 중 몇 개의 값만 필요하다면 _ 를 사용할 수 있다.
  • 튜플의 값에 인덱스로 접근할 수 있다.
  • 새로운 튜플을 만들 때 각 값의 이름을 붙여 선언할 수 있다.
  • 튜플의 값에 붙여진 이름으로 접근할 수 있다.
let http404Error = (404,"Not Found")
let (statusCode,statusMessage) = http404Error
let (justTheStatusCode, _) = http404Error

print("The status code is \\(http404Error.0)")

let http200Status = (statusCode : 200, description : 'OK')
print("The status code is \\(http200Status.statusCode)")
  • 튜플은 함수의 리턴 값으로써 유용하다. ex) 웹페이지 검색의 성공 또는 실패를 (Int, String) 타입으로 반환

Optionals

  • 옵셔널은 nil이 가능한 자료형
  • 옵셔널 바인딩은 값이 있는지 체크하고 해당 값을 가지는 상수나 변수를 만들고 사용할 수 있게 한다.
  • 옵셔널 바인딩에는 if, while 문이 사용될 수 있다.
  • 여러 개의 옵셔널 바인딩을 한번에 사용할 수 도 있다.
let possibleNumber = "123"

if let actualNumber = Int(possibleNumber) {
    print(actualNumber)	
} else{
    print("fail to conversion")
}
  • 옵셔널 변수 선언 시 ?는 암시적 옵셔널, !는 명시적 옵셔널을 의미한다.
  • !를 붙인 옵셔널은 처음 정의된 후에는 값이 존재한다고 보고 앞으로 모든 시점에서 존재한다고 확신할 수 있을 때 사용한다.
  • 암시적 옵셔널의 경우 다른 변수에서 사용할 때 등 !를 붙여주지 않아도 된다.
  • 암시적 옵셔널 값이 nil인데 접근하려고 한다면 런타임 오류가 발생한다. → nil check로 해결
let assumedString : String! = "An implicitly unwrapped optional string"
let implicitString : String = assumedString
let optionalString = assumedString // 타입은 String?

// nil check
if assumedString != nil {
  // do something
}


// 암시적 옵셔널 타입도 옵셔널 바인딩 가능
if let definiteString = assumedString {
  // do sometghing
}

Error Handling

  • 함수에서 에러가 발생될 수 있으면 throws를 사용해서 에러를 던진다.
func canThrowAnError() throws {
		
}

do {
    try canThrowAnError()
    //no error was thrown
} catch {
    // an error was thrown
}
  • 여러 개의 catch 블록을 사용하여 에러마다 분기처리 할 수 있다.
  • 에러는 개발자가 미리 선언할 수 있다. → [Error Hadling]
func makeASandwich() throws {
}

do {
  try makeASandwich()
  eatSandwich()
} catch SandwichError.outOfCleanDishes {
  washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
  buyGroceries(ingredients)
}

Assertions and Preconditions

  • Assertion과 Precondition은 런타임 시 발생하는 것들을 확인하는 것이다.
  • 추가 코드를 실행하기 전에 조건들을 확인하고 false라면 코드 실행이 중단되고 프로그램이 종료된다.
  • Error Handling 과는 다르게 복구 가능하거나 예상되는 오류에는 사용하지 않는다.
  • 발견 즉시 프로그램을 종료하여 잘못된 상태로 인한 피해를 줄이고 오류를 쉽게 디버깅할 수 있도록 돕는다.
  • Assertion과 Precondition은 조건들을 확인할 때 차이가 난다.

 

  • Assertion → 디버그 빌드에서만 체크
    • Assertion은 개발 과정에서 실수를 잡고 Precondition은 문제를 감지하는데 도움을 준다.
    • 프로덕션 빌드에서는 Assertion이 사용되지 않기 때문에 프로덕션 성능에 영향을 주지 않으면서 Assertion을 사용할 수 있다.
    • assert(::file:line:) → 조건을 확인
    • assertionFailure(_:file:line:) → 실패를 단언
let age = -3
assert(age >= 0, "A Person's age can't be less than zero")

if age > 10 {
  print("You can ride roller-coster")
} else if age >= 0 {
  print("You can ride ferris wheel")
} else {
  assertionFailure("A person's age can't be less than zero")
}
  • Precondition → 디버그 빌드, 프로덕션 빌드 모두 체크
    • preconditon은 조건이 거짓이 될 가능성이 있지만 코드가 실행되기 위해서 반드시 참이어야 할 때 사용.
    • precondition(::file:line:)
    • preconditionFailure(_:file:line:)를 사용해 실패 발생을 알릴 수 있다. 만약 unchekcedmode(-Ounchecked) 라면 preconditions는 체크되지 않는다. 이때 컴파일러는 조건들이 모두 참이라고 생각하고 진행한다.
    • 반면 fatalError(_:file:line) 함수는 이와 관계 없이 항상 체크되고 프로그램을 중지시킨다. 개발자는 fatalError를 개발 초기에 사용하여 치명적인 오류에 대해 항상 중지하도록 설정할 수 있다.
precondition(index > 0, "Index must be greater than zero")