티스토리 뷰

 회사에서 놀고있던 아이맥을 내 자리로 가져온 김에 ios 개발에도 살짝 발을 담구려고 한다. 

 

가장 먼저 swift 문법을 알아야 ios를 공부할 수 있기에, 공식 문서를 참조하여 열심히 핥아보려고 한다.

 

따로 글을 나누지 않고 이 포스팅 안에서 공식 문서가 설명하는 모든 문법을 정리할 것이다.

 

그럼 들어가보자.


1. Constants and Variables

  변수는 var, 상수는 let을 사용하여 선언하며, 다중으로 아래와 같이 선언하여 사용할 수도 있다. 

let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

var x = 0.0, y = 0.0, z = 0.0

2. Type Annotations

 run time 에러를 막기 위해 python도 type hint를 사용하듯, swift 또한 아래와 같은 type annotations 를 사용하여 컴파일 과정에서 미리 에러를 확인할 수 있다. 다중으로도 사용이 가능하다.

var welcomeMessage: String

var red, green, blue: Double

3. Printing Constants and Variables

 print() 함수로 콘솔에 출력을 전달할 수 있으며, 아래와 같이 사용하여 변수의 값을 check 할 수 있다.

var friendlyWelcome = "Hello!"
friendlyWelcome = "Bonjour!"

print("The current value of friendlyWelcome is \(friendlyWelcome)")
// Prints "The current value of friendlyWelcome is Bonjour!"

4. Comments

 주석은 아래와 같이 사용한다. 이는 JAVA와 동일하다.

// This is a comment.

/* This is also a comment
but is written over multiple lines. */

5. Semicolons

swift는 기본적으로 python과 같이 세미콜론이 필요하지 않은 언어이지만, python 과는 달리 개발자가 원한다면 사용해도 무방하다. 한 line에 아래와 같이 코드를 다중으로 적고 싶다면 사용해도 되지만, 권장하지는 않는다.

let cat = "🐱"; print(cat)
// Prints "🐱"

6. Tuples

다른 타입의 변수를 담을 수 있는 튜플 또한 swift에서 제공하는 feature  중 하나이다.

let http404Error = (404, "Not Found")
// http404Error is of type (Int, String), and equals (404, "Not Found")

let (statusCode, statusMessage) = http404Error

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

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

또한 아래와 같이 _ 를 사용하여 원치 않는 부분을 ignore할 수도 있다.

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// Prints "The status code is 404"

index를 사용하여 튜플의  element에 접근할 때는 간단하게 dot index 로 접근이 가능하다.

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

혹은 python의 dictionary와 비슷하게 각 element에 naming이 가능하다.

let http200Status = (statusCode: 200, description: "OK")

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

7. Optionals

 - Optional:

Optional은 기본적으로 해당 변수에 값이 들어갈 수도 있고 아닐 수도 있는 정해지지 않은 변수의 타입을 정하려고 할 때 사용한다. 나도 이 글을 작성하면서 거의 처음 보는 개념이라 매우 헷갈리는데, 천천히 정리해보자.

 

우선 Optionaldml 기본 형태는 아래와 같다.

let myFirstOptionalVar: Int?

변수의 타입 뒤에 ? 를 붙여주면 해당 변수는 Optional이 된다. 

 

 - nil:

Swift에는 nil 이라는 개념이 있는데, C언어의 포인터가 사용하지 않는 주소 값을 가리키는 개념이라기 보다는 value가 없는 null에 가까운 개념이다. swift는 기본적으로 변수를 처음 선언할 때 ? 와 함께 선언하는 optional변수가 아니라면 nil 값을 할당할 수 없기 때문에 nil과 optional은 한 세트와 같다고 볼 수 있다.

 

var optionalString: String = nil //에러
var optionalString: String? = nil

 

-Wrapping:

Optional 타입은 기본적으로 Wrap되어 있는 상태이다. 즉, Optional로 선언된 변수들은 값이 있는 것인지, nil인 것인지 wrap되어 있어서 모르는 상태인 것이다. 그렇기 때문에 wrap된 상태에서는 설령 변수에 값이 있다고 하더라고 바로 변수 값을 출력하는 것이 아닌 Optional(변수값)로 출력한다.

var optionalString: String? = “Hello”
print(optionalString)
// 출력 결과: Optional(“Hello”)

점점 더 헷갈리지만, 아래 String을 Int로 Casting 하는 예시를 확인해보자.

let possibleNumber = “123”
let convertedNumber = Int(possibleNumber)
print(convertedNumber)
// 출력 결과 : Optional(123)

"123"은 String이기 때문에, Int() 캐스팅은 초기화에 실패하지만 바로 에러가 나오는 것이 아닌 해당 변수를 Optional Int(Int?)로 선언한다.

 

- Forced Unwrapping: 

 앞선 예제에서처럼 출력 결과가 Optional(123)처럼 나오는 것은 사실 바람직한 출력이라고 볼 수 없다. Int? 타입이기 때문에 Int 처럼 활용을 할 수 없기 때문에... 이 때 올바른 int 값을 얻기 위해 사용하는 것이 바로 느낌표이다.

 

즉, optional로 선언했지만, 무조건 변수가 있는 상황이 보장된 경우, ! 를 사용하면 원하는 결과값을 얻을 수 있다.

var optionalString: String? = “Hello”
print(optionalString!)
// 출력 결과: Hello


let value1: String? = nil
let value2: String! = nil // 여기서는 에러가 아닙니다.
print(value) // nil 출력
print(value2) // error

 

- Optional Binding:

 해당 Optional 변수가 값을 가지고 있는 지 아닌지 판단하여 아래와 같이 사용하기 위한 Optional Binding이다.

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)


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")
}

 

 물론 let 말고 var를 사용하여 변수처럼 사용할 수도 있으며, 혹은 여러 개의 옵셔널 바인딩을 한 번에 사용할 수도 있다.

if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
}
// Prints "4 < 42 < 100"

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
// Prints "4 < 42 < 100"

여러 개의 옵셔널 바인딩을 한 번에 사용할 수도 있습니다.


8. Error Handling

 java나 다른 언어와 같이 thorws와 try/catch 문을 사용하여 에러 처리를 할 수 있다.

func canThrowAnError() throws {
    // this function may or may not throw an error
}
do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}

  위 예제에서 canThrowAnError 함수가 에러를 발생시키면 해당 에러를 catch 구문에서 잡아 처리할 수 있다.

이 때 catch에서 사용하는 에러의 종류는 보통 개발자가 미리 생성해놓는다.

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

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

 

에러 핸들링에 대한 내용은 여기서 기술하는 것보다 아래 가이드를 참조하는 것이 훨씬 자세하고 빠르다!

 

Guide: https://jusung.gitbook.io/the-swift-language-guide/language-guide/17-error-handling

 

에러 처리(Error Handling) - The Swift Language Guide (한국어)

vend(itemNamed:) 메소드의 구현에서 guard 구문을 사용해 snack을 구매하는 과정에서 에러가 발생하면 함수에서 에러를 발생시키고 빠르게 함수를 탈출할 수 있도록 합니다(early exit). vend(itemNamed:) 메소

jusung.gitbook.io


9. Debugging with Assertions

  런타임에서 assertion을 사용하여 조건이 거짓이며 프로그램을 중단하고, 에러를 확인할 수 있다.

let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 isn't >= 0.

만약 아래와 같이 if 구문에서 이미 조건이 충족되었다면, assertionFailure를 사용하여 실패를 알릴 수 있다.

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 
precondition은 조건이 거짓이 될 가능성이 있지만, 코드가 실행되기 위해선 반드시 참이여야 할 때 사용한다. 

let index = -1

precondition(index > 0, "index must be greater than zero")

preconditionFailure() 함수를 사용하여 실패가 발생했다는 것을 표시할 수 있으며, fatalError함수는 이와 관계없이 항상 체크되고 프로그램을 중지시킨다.

Comments