Swift: The Basics

yxnsx·2021년 4월 14일
0

Lang: Swift

목록 보기
1/1
post-thumbnail

Swift - The Basics



Constants and Variables

  • 상수는 let 키워드로 선언하고, 변수는 var 키워드로 선언한다.
  • 상수의 값은 한 번 설정되면 변경할 수 없지만, 변수는 다른 값으로 변경할 수 있다.
  • 상수와 변수는 사용하기 전, 선언이 우선되어야 한다.
let maximumNumberOfLoginAttempts = 10 // 상수
var currentLoginAttempt = 0 // 변수

var x = 0.0, y = 0.0, z = 0.0 // 여러 상수 또는 변수를 쉼표로 구분하여 한 줄에 선언할 수 있다.


Type Annotations

  • 상수 또는 변수가 저장할 수 있는 값의 유형을 명확히하기 위해 사용한다.
  • 상수 또는 변수 이름 뒤에 콜론, 공백, 타입을 차례로 선언한다.
  • 초기값이 지정되지 않은 경우, Type Annotations으로 타입을 선언한다.
  • 초기값이 지정된 경우, Type Annotations으로 타입이 선언되어 있지 않아도 타입 추론이 가능하다.
var welcomeMessage: String
var red, green, blue: Double // 한 줄에 선언한 변수들에 동일한 유형의 타입을 정의할 수 있다.


Naming Constants and Variables

  • 상수 및 변수의 이름은 유니코드 문자를 포함한 거의 모든 문자를 포함할 수 있다.
let π = 3.14159    // 가능
let 你好 = "你好世界" // 가능
let 🐶🐮 = "dogcow" // 가능

  • 상수 및 변수 이름에는 공백 문자, 수학 기호, 화살표, 개인용 유니코드 스칼라 값 등이 포함될 수 없다.
let s pace = "space" // 불가능
let space = "space"  // 가능

  • 상수 및 변수 이름이 숫자로 시작되어서는 안된다.
let 1one = 1 // 불가능
let one1 = 1 // 가능

  • where, func 등 스위프트 키워드와 동일한 이름으로 상수 및 변수의 이름을 지정해야 할 경우, 백틱(`)으로 묶어주어야 한다.
let where = "where"   // 불가능
let `where` = "where" // 가능


Comment

  • 한 줄 주석은 두 개의 슬래시(//)로 시작한다.
// This is a comment.

  • 여러 줄 주석은 슬래시와 별표(/*)로 시작하고 별표와 슬래시(*/)로 끝난다.
/* This is also a comment
but is written over multiple lines. */

  • 여러 줄 주석은 중첩 사용이 가능하다.
/* This is the start of the first multiline comment.
 /* This is the second, nested multiline comment. */
This is the end of the first multiline comment. */


Semicolons

  • Swift는 코드의 각 명령문 뒤에 세미콜론(;)을 작성할 필요가 없다.
  • 다만, 아래와 같이 한 줄에 여러 개의 개별문을 작성하기 위해서는 세미콜론이 필요하다.
let cat = "🐱"; print(cat)


Integers

✔️ Integer Bounds

  • Swift는 8, 16, 32, 64-bit 형식으로 정수를 제공한다.
  • minmax 속성을 사용하여 각 정수 유형의 최솟값과 최댓값에 접근할 수 있다.
let minValue = UInt8.min  // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max  // maxValue is equal to 255, and is of type UInt8

✔️ Int

  • 명시적으로 크기가 지정된 데이터 사용 또는 성능, 메모리 사용량 등 최적화를 위한 작업 등 특별한 경우가 아니라면 Int 정수값을 사용한다.
  • 32-bit 플랫폼에서의 Int size = Int32
  • 64-bit 플랫폼에서의 Int size = Int64

✔️ UInt

  • 부호 없는 정수 유형(0, 양수)만 제공한다.
  • 32-bit 플랫폼에서의 UInt size = UInt32
  • 64-bit 플랫폼에서의 UInt size = UInt64


Floating-Point Numbers

  • 부동 소수점 타입은 정수 타입보다 훨씬 더 넓은 범위의 값을 나타낼 수 있다.
  • Swift는 두 종류의 부동 소수점 타입을 제공한다.
    • 32-bit 부동 소수점 숫자 = Float
    • 64-bit 부동 소수점 숫자 = Double


Numeric Literals

  • 정수 리터럴은 다음과 같이 작성할 수 있다.
    • 10진법 숫자 - 접두어 필요 없음
    • 2진법 숫자 - 0b 접두어 필요
    • 8진법 숫자 - 0o 접두어 필요
    • 16진법 숫자 - 0x 접두어 필요
let decimalInteger = 17
let binaryInteger = 0b10001   // 2진법으로 나타낸 17
let octalInteger = 0o21       // 8진법으로 나타낸 17
let hexadecimalInteger = 0x11 // 16진법으로 나타낸 17

  • 부동 소수점 리터럴은 지수를 지닐 수 있다.
    • 10진법 숫자 (10exp씩 곱함)
      • 1.25e2 = 1.25 x 102 = 125.0
      • 1.25e-2 = 1.25 x 10-2 = 0.0125
    • 2진법 숫자 (2exp씩 곱함)
      • 0xFp2 = 15 x 22 = 60.0
      • 0xFp-2 = 15 x 2-2 = 3.75
let decimalDouble = 12.1875     // = 12.1875
let exponentDouble = 1.21875e1  // = 12.1875
let hexadecimalDouble = 0xC.3p0 // = 12.1875

  • 숫자 리터럴은 쉽게 읽을 수 있도록 추가적인 형식을 포함할 수 있다.
  • 정수와 부동 소수점 모두 0으로 채울 수 있으며, 밑줄을 포함할 수 있다.
  • 이러한 형식은 리터럴의 기본 값에 영향을 주지 않는다.
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1


Numeric Type Conversion

✔️ Integer Conversion

  • 상수 또는 변수에 저장할 수 있는 숫자의 범위는 타입마다 다르기 때문에 타입 변환이 필요하다.
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)

✔️ Integer and Floating-Point Conversion

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine // Int -> Double 변환
let integerPi = Int(pi) // Double -> Int 변환


Type Aliases

  • 타입 별칭은 기존 타입의 대체 이름을 정의한다.
  • 상황에 따라 더 적절한 이름으로 기존 유형을 참조하는 경우 유용하다.
  • 타입 별칭을 정의하면 원래의 이름을 사용할 수 있는 모든 곳에서 별칭을 사용할 수 있다.
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min


Booleans

  • Boolean 값은 true 또는 false만 될 수 있는 logical 값이다.
  • 이러한 Boolean 값은 if와 같은 조건문으로 작업할 때 특히 유용하게 활용할 수 있다.
let orangesAreOrange = true
let turnipsAreDelicious = false

if turnipsAreDelicious {
    print("Mmm, tasty turnips!")
} else {
    print("Eww, turnips are horrible.")
}


Tuples

  • 튜플은 여러 값을 단일 복합 값으로 그룹화한다.
  • 튜플은 반환 값이 여러 개인 함수에서 특히 유용하게 사용할 수 있다.
  • 튜플 내의 값은 모든 유형이 될 수 있으며, 서로 동일한 유형일 필요는 없다.
let http404Error = (404, "Not Found")
// http404Error is of type (Int, String), and equals (404, "Not Found")

  • 튜플 내의 값은 각각의 상수 또는 변수로 분해할 수 있으며, 다음과 같은 방법으로 각각에 접근할 수 있다.
let (statusCode, statusMessage) = http404Error

// Prints "The status code is 404"
print("The status code is \(statusCode)")

// Prints "The status message is Not Found"
print("The status message is \(statusMessage)")

  • 튜플 내의 값 중 일부만 필요할 경우, 언더스코어(_)를 이용하여 불필요한 부분을 무시할 수 있다.
let (justTheStatusCode, _) = http404Error

// Prints "The status code is 404"
print("The status code is \(justTheStatusCode)")

  • 0부터 시작하는 인덱스를 통해 튜플 내의 각 값에 접근할 수도 있다.
// Prints "The status code is 404"
print("The status code is \(http404Error.0)")

// Prints "The status message is Not Found"
print("The status message is \(http404Error.1)")

  • 튜플을 정의할 시, 튜플 내의 각 값에 이름을 지정할 수 있다.
  • 튜플 내의 각 값에 이름을 지정한 경우, 해당 값에 접근하기 위해 지정한 이름을 이용할 수 있다.
let http200Status = (statusCode: 200, description: "OK")

// Prints "The status code is 200"
print("The status code is \(http200Status.statusCode)")

// Prints "The status message is OK"
print("The status message is \(http200Status.description)")


Optionals

  • optional은 상수 또는 변수가 "값이 없음"을 지닐 수 있음을 나타낸다.
  • optional은 두 가지 상태를 나타낼 수 있다.
    • 값이 있고, 그 값에 접근하기 위해 optional을 해제할 수 있는 상태
    • 값이 없는 상태
  • 스위프트의 optional은 특별한 상수 없이 어떤 타입에도 값이 없음을 나타낼 수 있게 한다.

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type "Int?", or "optional Int"
  • 위의 예시에서 possibleNumber의 값으로 "Hello, world"등이 지정될 수 있다.
  • 이 때, convertedNumber에서의 Int(possibleNumber) 변환은 실패할 수 있다.
  • 이러한 경우를 위해 convertedNumber의 값은 Int? 또는 optional Int로 추론된다.

✔️ nil

  • 값이 없는 상태에 nil이라는 특정한 값을 할당하여 optional 변수로 지정할 수 있다.
  • 기본값을 지정하지 않고 optional 변수를 정의할 경우, 변수는 자동으로 nil 값으로 설정된다.
// serverResponseCode contains an actual Int value of 404
var serverResponseCode: Int? = 404

// serverResponseCode now contains no value
serverResponseCode = nil

// surveyAnswer is automatically set to nil
var surveyAnswer: String?

✔️ If Statements and Forced Unwrapping

  • if문으로 optionalnil 값을 비교해서 optional이 값을 지니고 있는지 알아낼 수 있다.
if convertedNumber != nil {
    print("convertedNumber has an integer value of \(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."

✔️ Optional Binding

  • optional binding을 통해 optional이 값을 지니고 있는지 알아낼 수 있다.
  • 값이 존재할 경우, 해당 값을 상수 또는 변수로 사용할 수 있다.
if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("The string \"\(possibleNumber)\" couldn't be converted to an integer")
}
// Prints "The string "123" has an integer value of 123"

✔️ Implicitly Unwrapped Optionals

  • optional 값이 항상 값을 지니고 있다고 가정할 수 있는 경우, 해당 값에 액세스 할 때마다 값의 유무를 확인할 필요가 없다.
  • optional로 선언된 변수 사용시, 해당 변수명 뒤에 느낌표를 넣어 항상 값을 지니고 있음을 나타낼 수 있다.
  • 해당 변수 선언시, 자료형 뒤에 느낌표를 넣어 항상 값을 지니고 있음을 나타낼 수 있다.
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation point

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation point


Error Handling

  • 실행 중 프로그램에서 나타나는 문제의 에러 상황에 따라 응답할 때 사용한다.
  • 에러 처리는 내재하는 실패 원인을 판별하고, 필요한 경우 프로그램의 다른 부분으로 해당 에러를 전달할 수 있다.
  • 에러 상황을 마주한 함수는 에러를 throws하고, 해당 함수의 호출자는 에러를 잡아내고 적절하게 응답할 수 있다.
  • 이러한 함수는 에러를 throws할 수 있다는 것을 나타내기 위해 throws 키워드를 포함해야 한다.
func canThrowAnError() throws {
    // this function may or may not throw an error
}

  • swift는 catch절에 의해 처리될 때까지 해당 범위 내에서 자동으로 에러를 전달한다.
  • do문은 에러를 하나 이상의 catch절로 전파하는 새 구간을 생성한다.
do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}

func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}
  • 위의 예에서 makeASandwich() 함수는 깨끗한 접시가 없을 경우 또는 재료가 빠졌을 경우 에러를 발생시킨다.
  • 아무런 에러도 발생하지 않았을 경우,eatASandwich() 함수가 호출된다.
  • do문으로 감싸인 함수 호출에서는 어떠한 에러라도 catch절로 전달된다.
  • 에러가 발생했고 해당 에러가 SandwichError.outOfCleanDishes와 일치할 경우, washDishes() 함수가 호출된다.
  • 에러가 발생했고 해당 에러가 SandwichError.missingIngredients와 일치할 경우, catch 패턴에 의해 캡쳐된 [String] 값과 함께 buyGroceries(_:) 함수가 호출된다.


Assertions and Preconditions

✔️ Debugging with Assertions

  • swift의 표준 라이브러리에서 assert(_:_:file:line:)를 호출하여 assertion을 작성할 수 있다.
  • 결과가 true일 경우, 코드 실행이 계속된다.
  • 결과가 false일 경우, assertion에 실패하여 프로그램이 종료된다.
  • true 또는 false를 판별할 수 있는 표현식과 결과가 false일 경우 보여질 메시지를 이 함수에 전달한다.
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 isn't >= 0.

  • 단순히 조건만을 반복할 경우에는 메시지를 생략할 수 있다.
assert(age >= 0)

  • 조건을 이미 확인한 경우, assertionFailure(_:file:line:)함수를 호출하여 assertion이 실패했는지 알릴 수 있다.
if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
} else if age >= 0 {
    print("You can ride the ferris wheel.")
} else {
    assertionFailure("A person's age can't be less than zero.")
}

✔️ Enforcing Preconditions

  • 조건이 false가 될 가능성이 있을 경우 precondition을 사용하지만, 코드가 계속 실행되기 위해서는 반드시 true여야 한다.
  • 어떠한 값이 범위를 벗어나지는 않는지, 함수에 유효한 값이 전달되는지를 체크하기 위해 precondition을 사용한다.
  • precondition(_:_:file:line:) 함수를 호출하여 precondition을 작성할 수 있다.
  • true 또는 false를 판별할 수 있는 표현식과 결과가 false일 경우 보여질 메시지를 이 함수에 전달한다.
  • preconditionFailure(_:file:line:)함수를 호출하여 precondition이 실패했는지 알릴 수 있다.
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 isn't >= 0.


📝 References

0개의 댓글