assertguard

애플리케이션이 동작 도중에 생성하는 다양한 연산 결과값을 동적으로 확인하고 안전하게 처리할 수 있도록 확인하고 빠르게 처리할 수 있습니다.


소스코드


Assertion

assert(_:_:file:line:) 함수를 사용합니다. assert 함수는 디버깅 모드에서만 동작합니다. 배포하는 애플리케이션에서는 제외됩니다. 

주로 디버깅 중 조건의 검증을 위하여 사용합니다.

var someInt: Int = 0

// 검증 조건에 부합하므로 지나갑니다
assert(someInt == 0, "someInt != 0")

someInt = 1
//assert(someInt == 0) // 동작 중지, 검증 실패
//assert(someInt == 0, "someInt != 0") // 동작 중지, 검증 실패
// assertion failed: someInt != 0: file guard_assert.swift, line 26


func functionWithAssert(age: Int?) {
    
    assert(age != nil, "age == nil")
    
    assert((age! >= 0) && (age! <= 130), "나이값 입력이 잘못되었습니다")
    print("당신의 나이는 \(age!)세입니다")
}

functionWithAssert(age: 50)
//functionWithAssert(age: -1) // 동작 중지, 검증 실패
//functionWithAssert(age: nil) // 동작 중지, 검증 실패


assert(_:_:file:line:)와 같은 역할을 하지만 실제 배포 환경에서도 동작하는 precondition(_:_:file:line:) 함수도 있습니다. 함께 살펴보세요.



빠른 종료 - Early Exit

guard를 사용하여 잘못된 값의 전달 시 특정 실행구문을 빠르게 종료합니다. 디버깅 모드 뿐만 아니라 어떤 조건에서도 동작합니다. guardelse 블럭 내부에는 특정 코드블럭을 종료하는 지시어(return, break 등)가 꼭 있어야 합니다. 타입 캐스팅, 옵셔널과도 자주 사용됩니다. 그 외에도 단순 조건 판단 후 빠르게 종료할 때도 용이합니다.

func functionWithGuard(age: Int?) {
    
    guard let unwrappedAge = age,
        unwrappedAge < 130,
        unwrappedAge >= 0 else {
        print("나이값 입력이 잘못되었습니다")
        return
    }
    
    print("당신의 나이는 \(unwrappedAge)세입니다")
}

var count = 1

while true {
    guard count < 3 else {
        break
    }
    print(count)
    count += 1
}
// 1
// 2


func someFunction(info: [String: Any]) {
    guard let name = info["name"] as? String else {
        return
    }
    
    guard let age = info["age"] as? Int, age >= 0 else {
        return
    }
    
    print("\(name): \(age)")
    
}

someFunction(info: ["name": "jenny", "age": "10"])
someFunction(info: ["name": "mike"])
someFunction(info: ["name": "yagom", "age": 10]) // yagom: 10


관련문서

* The Swift Programming Language - Control Flow - Early Exit

* The Swift Programming Language - The Basics - Assertion





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 


저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

익스텐션  (0) 2017.07.20
프로토콜  (0) 2017.07.17
assert와 guard  (0) 2017.07.13
타입캐스팅  (2) 2017.07.10
옵셔널 체이닝  (0) 2017.07.06
인스턴스의 생성과 소멸  (0) 2017.07.03
Posted by yagom

컬렉션 타입

  • Array - 순서가 있는 리스트 컬렉션 
  • Dictionary - `키`와 `값`의 쌍으로 이루어진 컬렉션 
  • Set - 순서가 없고, 멤버가 유일한 컬렉션 

소스코드



Array

Array는 멤버가 순서(인덱스)를 가진 리스트 형태의 컬렉션 타입입니다.


Array 선언 및 생성

Array는 여러 리터럴 문법을 활용할 수 있어서 표현 방법이 다양합니다

// 빈 Int Array 생성
var integers: Array = Array()

// 같은 표현
// var integers: Array = [Int]()
// var integers: Array = []
// var integers: [Int] = Array()
// var integers: [Int] = [Int]()
// var integers: [Int] = []
// var integers = [Int]()


Array 활용

integers.append(1)
integers.append(100)

// Int 타입이 아니므로 Array에 추가할 수 없습니다
//integers.append(101.1)

print(integers)	// [1, 100]

// 멤버 포함 여부 확인
print(integers.contains(100)) // true
print(integers.contains(99)) // false

// 멤버 교체
integers[0] = 99

// 멤버 삭제
integers.remove(at: 0)
integers.removeLast()
integers.removeAll()

// 멤버 수 확인
print(integers.count)

// 인덱스를 벗어나 접근하려면 익셉션 런타임 오류발생
//integers[0]


let을 사용하여 Array를 선언하면 불변 Array가 됩니다

let immutableArray = [1, 2, 3]

// 수정이 불가능한 Array이므로 멤버를 추가하거나 삭제할 수 없습니다
//immutableArray.append(4)
//immutableArray.removeAll()


Dictionary

Dictionary는 의 쌍으로 이루어진 컬렉션 타입입니다.


Dictionary의 선언과 생성

Dictionary는 여러 리터럴 문법을 활용할 수 있어서 표현 방법이 다양합니다

// Key가 String 타입이고 Value가 Any인 빈 Dictionary 생성
var anyDictionary: Dictionary = [String: Any]()

// 같은 표현
// var anyDictionary: Dictionary  = Dictionary()
// var anyDictionary: Dictionary  = [:]
// var anyDictionary: [String: Any] = Dictionary()
// var anyDictionary: [String: Any] = [String: Any]()
// var anyDictionary: [String: Any] = [:]
// var anyDictionary = [String: Any]()


Dictionary 활용

// 키에 해당하는 값 할당
anyDictionary["someKey"] = "value"
anyDictionary["anotherKey"] = 100

print(anyDictionary) // ["someKey": "value", "anotherKey": 100]

// 키에 해당하는 값 변경
anyDictionary["someKey"] = "dictionary"
print(anyDictionary) ["someKey": "dictionary", "anotherKey": 100]

// 키에 해당하는 값 제거
anyDictionary.removeValue(forKey: "anotherKey")
anyDictionary["someKey"] = nil
print(anyDictionary)

let을 사용하여 Dictionary를 선언하면 불변 Dictionary가 됩니다


let emptyDictionary: [String: String] = [:]
let initalizedDictionary: [String: String] = ["name": "yagom", "gender": "male"]

// 불변 Dictionary이므로 값 변경 불가
//emptyDictionary["key"] = "value"

키에 해당하는 값을 다른 변수나 상수에 할당하고자 할 때는 옵셔널과 타입 캐스팅 파트에서 다룹니다

// "name"이라는 키에 해당하는 값이 없을 수 있으므로 
// String 타입의 값이 나올 것이라는 보장이 없습니다.
// 컴파일 오류가 발생합니다
let someValue: String = initalizedDictionary["name"]


Set

Set는 순서가 없고, 멤버가 유일한 것을 보장하는 컬렉션 타입입니다.

Set의 선언과 생성

// 빈 Int Set 생성
var integerSet: Set = Set()
integerSet.insert(1)
integerSet.insert(100)
integerSet.insert(99)
integerSet.insert(99)
integerSet.insert(99)

print(integerSet) // [100, 99, 1]
print(integerSet.contains(1)) // true
print(integerSet.contains(2)) // false

integerSet.remove(100)
integerSet.removeFirst()

print(integerSet.count) // 1


Set는 집합연산에 많이 활용됩니다

// Set는 집합 연산에 꽤 유용합니다
let setA: Set = [1, 2, 3, 4, 5]
let setB: Set = [3, 4, 5, 6, 7]

// 합집합
let union: Set = setA.union(setB)
print(union) // [2, 4, 5, 6, 7, 3, 1]

// 합집합 오름차순 정렬
let sortedUnion: [Int] = union.sorted()
print(sortedUnion) // [1, 2, 3, 4, 5, 6, 7]

// 교집합
let intersection: Set = setA.intersection(setB)
print(intersection) // [5, 3, 4]

// 차집합
let subtracting: Set = setA.subtracting(setB)
print(subtracting) // [2, 1]


생각해보기

다음과 같은 경우에는 각각 어떤 컬렉션 타입을, 상수/변수 선언 중 어떤 것을 사용하면 유용할지 생각해 봅시다. 

  • 영어 알파벳 소문자를 모아두는 컬렉션
  • 책의 제목과 저자 정리를 위한 컬렉션
  • 우리반 학생 명부 작성을 위한 컬렉션








by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 

저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

조건문  (0) 2017.05.29
함수  (2) 2017.05.25
컬렉션 타입  (0) 2017.05.22
데이터 타입  (0) 2017.05.18
상수와 변수  (0) 2017.05.15
이름짓기, 콘솔로그, 문자열 보간법  (0) 2017.05.11
Posted by yagom

상수, 변수의 선언




소스코드


  • 상수 선언 키워드 let
  • 변수 선언 키워드 var


let 이름: 타입 =
var 이름: 타입 =


값의 타입이 명확하다면 타입은 생략 가능

let 이름 = 값  
var 이름 = 값
let constant: String = "차후에 변경이 불가능한 상수 let"
var variable: String = "차후에 변경이 가능한 변수 var"

variable = "변수는 이렇게 차후에 다른 값을 할당할 수 있지만"
// constant = "상수는 차후에 값을 변경할 수 없습니다" // 오류발생


상수 선언 후에 나중에 값 할당하기


나중에 할당하려고 하는 상수나 변수는 타입을 명시해주어야 합니다

let sum: Int
let inputA: Int = 100
let inputB: Int = 200

// 선언 후 첫 할당
sum = inputA + inputB

// sum = 1 // 그 이후에는 다시 값을 바꿀 수 없습니다, 오류발생

// 변수도 물론 차후에 할당하는 것이 가능합니다
var nickName: String

nickName = "yagom"

// 변수는 차후에 다시 다른 값을 할당해도 문제가 없지요
nickName = "야곰"


생각해보기


다음과 같은 경우에 각 값은 상수와 변수 중 어느 것으로 선언하는 것이 더 좋을지 생각해 봅시다.

OOO name = "yagom"
OOO numberToAdd = 5
OOO pi = 3.14195
OOO maxItemCount = 1000


관련문서





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   




저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

컬렉션 타입  (0) 2017.05.22
데이터 타입  (0) 2017.05.18
상수와 변수  (0) 2017.05.15
이름짓기, 콘솔로그, 문자열 보간법  (0) 2017.05.11
스위프트 시작하기  (0) 2017.05.08
Swift - 프로토콜, 익스텐션  (0) 2017.03.07
Posted by yagom


오늘의 주제

Objective-C의 상수와 스위프트의 상수


안녕하세요 야곰입니다.

Objective-C를 쓰다가 스위프트로 넘어왔을 때 고민되었던 부분 중의 하나인 스위프트의 상수에 관해 이야기해 보려 합니다.


혼자 프로젝트를 진행하다 보면 상수의 필요성을 많이 느낄 수 없을지 모르지만, 누군가 협업을 하게 된다면, 혹은 미래 또는 과거의 나와 협업(?)을 하게 된다면 상수의 필요성을 많이 느끼게 됩니다. 바꾸면 안 되는 데이터를 실수로 바꿔서 난감했던 경험이 없나요? 혹시 그런 적이 있다면 상수의 필요성에 대해서는 많이 공감하실 것으로 생각됩니다.


* 오해가 생길 소지의 표현들이 있어서 처음 발행 이후 조금 수정하였습니다. 좋은 의견 주신 과니님 고맙습니다 :)


사라진 const


사실 저는 Objective-C에서 특별한 경우가 아니면 const를 많이 사용하지 않았습니다(반성).


그런데 스위프트에서는 전역이든 지역이든 데이터를 저장할 공간(변수 또는 상수)에는 var 또는 let을 사용하여 변수인지 상수인지 명확히 명시해 주어야 하므로 상수에 대한 고민을 많이 하게 되었습니다.


사실 지역상수가 필요한 경우에 const 키워드를 쓰는 귀찮음 때문에 상수를 많이 사용하지 않았는데 스위프트에서는 var 또는 let을 선택해야 하는 시간이 조금 걸렸지만, 지금은 큰 시간 들일 필요 없이 자연스럽게 상수를 많이 사용하고 있습니다. 또, 혹시라도 상수로 사용해야 하는 경우임에도 변수로 선언하고 사용한다면 Xcode에서 변수 대신 상수를 사용하는 게 어떻냐는 경고를 보여줍니다. 




[Xcode의 경고]


지역상수


지역상수를 사용하는 경우에는 사실 Objective-C와 크게 다를 바 없이 사용할 수 있습니다. 상수의 이름을 지어주는 명명법도 크게 다를 바 없습니다. 

상수로 사용할 변수 앞에 const를 붙여 쓴 것처럼 let을 사용하여 상수를 선언하여 사용하면 됩니다.



// Objective-C
const NSInteger someConstant = 100;


// Swift
let someConstant: Int = 100



전역상수


전역상수를 사용할 때 조금 더 생각해보아야 할 것들이 있습니다. 저는 처음 스위프트를 사용할 때 별생각 없이 Objective-C에서 사용하던 것과 같은 명명법으로 전역상수를 사용했습니다.


// Objective-C NSInteger const  YGSomeGlobalConstant = 100;


// Swift
let YGSomeGlobalConstant: Int = 100


그런데 Objective-C에서 'YG'와 같이 접두어(prefix)를 붙이는 것은 Objective-C에는 네임스페이스(name space)가 없기 때문인데, 스위프트에는 이 단점을 극복했다는 것에 대한 생각이 문득 스쳤습니다.


Objective-C에는 네임스페이스가 없어서 전역변수를 선언하고 사용할 때 꽤 골치가 아팠습니다. 귀찮기도 아주 귀찮았죠. 이름도 매우 길어지기만 했습니다. 열거형(enum)은 정수밖에 지원하지 않기 때문에 다른 타입의 값들은 관련된 상수끼리 묶어 쓰기도 어렵기도 했지요.


// Objective-C의 상수들... // 네임스페이스가 없기 때문에 // 연관된 상수들을 접두어를 사용하여 표현합니다 // 요일 상수들 NSString *const YGWeekMonday = @"MON"; NSString *const YGWeekTuesday = @"TUE"; NSString *const YGWeekWednesday = @"WED"; NSString *const YGWeekThursday = @"THU"; NSString *const YGWeekFriday = @"FRI"; NSString *const YGWeekSaturday = @"SAT"; NSString *const YGWeekSunday = @"SUN"; // 네트워킹 관련 상수들 NSTimeInterval const YGNetworkingTimeoutInterval = 10.0f; NSUInteger const YGNetworkingMaxRetryCount = 3; NSString *const YGNetworkingBaseURLString = @"https://abc.com";


정말 보기만 해도 정신이 없습니다. 또, 실수로 복사 붙여넣기를 하다가 중복된 값을 넣었다면 컴파일 오류가 발생하지 않기 때문에 실수를 찾아내기도 매우 어려워집니다.


스위프트에서는 이런 전역 상수들을 조금 더 멋진 방법으로 표현해 볼 수 있습니다. 타입 내부에 다른 타입을 정의하는 방법으로 네임스페이스를 사용할 수 있습니다. 더군다나 네임스페이스 덕분에 접두어는 더 이상 스위프트에서 사용하지 않습니다.


// Week라는 구조체 타입 내부에
// 여러 타입 상수를 선언
struct Week {
    static let mon: String = "MON"
    static let tue: String = "TUE"
    static let wed: String = "WED"
    static let thu: String = "THU"
    static let fri: String = "FRI"
    static let sat: String = "SAT"
    static let sun: String = "SUN"
}

// 실제 사용시 Week.mon // "MON" Week.sat // "SAT"


처음에 이렇게 선언해 보았습니다. 그런데 만약 복사 붙여넣기를 하다가 실수로 중복된 값을 넣는다면...? 가령 "SUN"을 넣어야 하는데 "SAT"를 넣어버렸다면? 이때는 중복 값이 들어있는지 확인할 수 없습니다. 물론 의도적으로 다른 이름의 상수에 같은 값을 넣을 수도 있지만 그렇지 않은 경우에는 낭패입니다.


그래서 이렇게 개선해 봅니다.


// 열거형의 연관 값(associated value)을 사용하여
// 상수처럼 사용
enum Week: String {
    case mon = "MON"
    case tue = "TUE"
    case wed = "WED"
    case thu = "THU"
    case fri = "FRI"
    case sat = "SAT"
    case sun = "SUN"
}

// 실제 사용시 Week.mon.rawValue // "MON" Week.sat.rawValue // "SAT"



이렇게 사용하면 열거형 내부의 연관 값이 중복되는 경우에 컴파일오류가 발생하게 됩니다. 그래서 미리 실수를 발견하기도 좋습니다.


또, 위의 Objective-C로 선언했던 네트워킹 관련 상수를 스위프트에서 선언한다면 이렇게 바꿔볼 수 있을 것 같습니다.


// Objective-C NSTimeInterval const YGNetworkingTimeoutInterval = 10.0f; NSUInteger const YGNetworkingMaxRetryCount = 3; NSString *const YGNetworkingBaseURLString = @"https://abc.com";
// 사용 YGNetworkingTimeoutInterval // 10.0


// Swift
struct Networking {
    static let timeoutInterval: TimeInterval = 10.0
    static let maxRetryCount: Int = 3
    static let baseURL: URL? = URL(string: "https://abc.com")
}

// 사용

Networking.timeoutInterval // 10.0


이처럼 꼭 열거형의 연관 값을 사용하지 않고 용도에 맞게 구조체의 타입 상수(static let)로 사용해도 좋습니다. 


상수뿐만 아니라 전역변수, 전역함수(메서드) 등에도 충분히 응용할 수 있습니다.


또한 구조체 내부에 다른 타입(구조체, 클래스, 열거형) 등등 몇 단계를 걸쳐 내부 타입을 정의할 수 있기 때문 연관된 값을 타입의 타입의 타입까지 여러 번에 걸쳐 정의도 가능합니다.



struct CalendarItem {
    typealias Year = Int
    typealias Day = Int
    
    enum Week: String {
        case mon = "MON", tue = "TUE" //...
    }
    
    enum Month: Int {
        case jan = 1, feb, mar //...
    }
    
    static let startYear: Int = 1970
    static let startMonth: CalendarItem.Month = .jan
    
    struct Date {
        var day: Day = 1
        var weekDay: CalendarItem.Week = .mon
        var month: CalendarItem.Month = .jan
        var year: Year = CalendarItem.startYear
    }
}

var userBirthday: CalendarItem.Date userBirthday = CalendarItem.Date.init(day: 10, weekDay: .tue, month: .mar, year: 2017)



마치며


같은 Cocoa 플랫폼 위에서 코드를 작성하는데도 불구하고 역시나 언어의 특성을 살려 새로이 구조를 설계하기는 쉽지 않습니다 하핳


무언가 두서없이 써내려간 느낌입니다만, 잘 이해가 가지 않거나 궁금한 점이 있다면 댓글 남겨주세요 :D





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


저작자 표시 비영리 변경 금지
신고
Posted by yagom


오늘의 주제

1. 스위프트에서의 명명법
2. 변수, 상수의 선언

3. 기초 데이터 타입

안녕하세요, 야곰입니다. 

지난 포스팅에서는 스위프트가 어떤 언어인지에 대해 잠시 살펴보았습니다. 


2017/01/23 - [Swift] - Swift란 어떤 언어인가?


이번에는 스위프트의 아주 기초적인 문법에 대해 알아보겠습니다 :)


이름짓기

프로그래밍을 할 때 우리는 변수, 상수, 함수, 타입 등을 제각각 구분할 수 있도록 이름을 지어주어야 합니다. 그런데 각 언어마다 이름을 지어줄 때 지켜야 하는 규칙들이 있습니다. 스위프트에도 마찬가지로 이름을 지을 때 생각해 주어야 할 점들이 있는데요, 간략히 알아보겠습니다.

  • 이름은 유니코드에서 지원하는 어떤 문자(한글, 한자, 영문, 숫자, 이모티콘 등등)라도 사용할 수 있습니다. 다만, 다음과 같은 예외의 경우는 사용할 수 없습니다. 
    • 스위프트에서 미리 사용하고 있는 예약어 또는 키워드
    • 해당 코드 범위 내에서 이미 사용하고 있는 기존의 이름과 동일한 이름 
    • 연산자로사용될수있는기호(+, -,*,/)
    • 숫자로 시작하는 이름
    • 공백이 포함된 이름 
  • 함수, 메서드, 인스턴스 이름은 첫 글자를 소문자로 사용하는 소문자 카멜케이스(Lower Camel Case)를 사용합니다. 
  • 클래스, 구조체, 익스텐션, 프로토콜, 열거형 이름은 타입의 이름이기 때문에 첫 글자를 대문자로 사용하는 대문자 카멜케이스(Upper Camel Case)를 사용합니다.
  • 대소문자를 구별합니다. 예를 들어 Var와 var를 따로 인식합니다.

예약어와 키워드 


예약어는 프로그래밍 언어에서 미리 사용하기로 약속되어 있는 단어로, 식별자로 사용할 수 없는 단어를 뜻합니다. 키워드는 프로그래밍 언어 문법의 일부로, 특별한 의미를 갖는 단어를 뜻합니다. 스위프트의 키워드는 대부분 예약어입니다.



변수와 상수

변수

프로그래밍을 해보신 분들이라면 변수와 상수가 어떤 역할을 하는지 다들 알고 계시겠지요?
프로그램에서 사용되는 데이터를 메모리에 임시적으로 저장하기 위하여 변수나 상수를 이용합니다. 이때 변수와 상수는 특정 데이터 타입에 해당하는 값의 이름입니다. 변수는 생성 후 데이터 값을 변경할 수 있지만, 상수는 한 번 값을 설정하면 추후에는 변경할 수 없습니다. 

스위프트에서 변수를 생성하려면 var 키워드를 사용합니다. var [변수명]: [데이터 타입] = [값] 의 형태로 선언합니다. 변수를 생성할 때 데이터 타입은 생략할 수 있습니다. 큰따옴표(“)로 묶인 데이터는 문자열을 의미합니다.

var name: String = "yagom" var age: Int = 100 var job = "iOS Programmer" // 타입 추론이 사용되었습니다 var height = 181.5 // 타입 추론이 사용되었습니다 age = 99 // 변수는 값을 변경해 줄 수 있습니다. job = "Writer" // 값을 변경할 때에는 기존과 동일한 타입의 값을 할당해 주어야 합니다.



주석(Comment)


코드 중간중간 // 기호 뒤에 녹색으로 붙은 글귀는 주석입니다. 즉, 코드에 해당하는 설명을 덧붙이기 위한 메모라고 생각하면 됩니다. 주석은 프로그램이 실행될 때 코드로서 실행되지는 않습니다. 사람이 코드를 읽기 편하도록 하기위한 보조수단입니다. 


타입 추론


변수나 상수를 생성할 때 데이터 타입을 생략하면 컴파일러가 변수 값의 타입을 추론하여 타입을 지정합니다. 애플은 이런 타입 추론을 스위프트의 강력한 기능이라고 소개했지만, 스위프트에 익숙하지 않은 프로그래머에게는 오히려 독이 될 수 있습니다. 그러다 보니 저는 타입 추론을 많이 사용하지는 않습니다. 자칫 잘못된 타입 추론으로 인해 오류가 생기면 이 오류를 찾는데 상당한 시간이 걸릴 수도 있습니다. 타입을 명확히 지정하지 않아 발생하는 오류를 찾아내는 것보다 처음부터 타입을 명시하는 편이 시간을 더 절약할 수 있습니다. 


[플레이그라운드 실행결과]


스위프트에서 세미콜론 


스위프트에서 명령구문 뒤에 세미콜론(;)을 붙이는 것은 선택사항입니다. 기존 프로그래밍 언어의 습관대로 구 문 뒤에 세미콜론을 붙이셔도 상관 없습니다. 



상수

스위프트에서는 let 키워드를 사용해서 상수를 생성합니다. let [상수명]: [데이터 타입] = [값] 의 형태로 선언합니다. 변수 생성과 마찬가지로 상수 생성 때도 데이터 타입을 생략할 수 있습니다. 

let name: String = "yagom" // 차후 변경하지 않는 값은 상수로 선언합니다.
var age: Int = 100
var job = "iOS Programmer"  // 타입 추론이 사용되었습니다.
let constHeight = 181.5

age = 99        // 변수는 값을 변경할 수 있습니다.
job = "Writer"  // 값을 변경할 때에는 기존과 동일한 타입의 값을 할당해야 합니다.
name = "야곰"     // 상수로 선언된 값은 변경할 수 없습니다. 오류가 발생합니다.


변수를 사용하지 않고 상수를 사용하는 이유는 다양합니다. 하지만 가장 중요한 이유는 가독성입니다. 


상수는 변하지 않는 값입니다. 때문에 상수로 값을 선언하면, 이후 코드에서 값의 변화가 없다는 사실을 주석이나 API 문서 등을 살펴보지 않고서도 직관적으로 알 수 있습니다. 즉, 차후 값의 변경을 신경쓰지 않아도 된다 는 것입니다. 예를 들어 원주율 값은 (아직까지는) 공식적으로 불변하는 값이므로 상수로 선언하는 것이 좋습니다. 


또, 특정 값에 특별한 의미를 부여할 때 사용할 수도 있습니다. 예를 들어 입력받는 수의 최대 크기가 100이 라고 한다면, 100이라는 숫자에 의미를 부여하기 위해 let maxInputValue = 100 등으로 선언해두면 차후에 직관적으로 읽기도, 사용하기도 편리할 것입니다.  


[플레이그라운드 실행결과]


플레이그라운드 실행결과를 보면 왼쪽에 빨간 동그라미를 통해 해당 줄에서 오류가 발생했음을 확인할 수 있습니다. 상수의 값을 차후에 변경하려고 했기 때문에 컴파일러가 프로그래머가 발생시킨 오류를 알려준 것입니다. 오류가 발생한 곳을 삭제하거나 수정하면 정상작동 합니다.

[오류 수정 후 플레이그라운드 실행결과]



콘솔 로그 남기기

프로그램에서 로그란, 애플리케이션의 상태 또는 애플리케이션 내부 로직의 흐름을 관찰할 수 있도록 출력한 정보를 의미합니다. 콘솔 로그(Console Log)는 디버깅 중 디버깅 콘솔에 보여줄 로그를 뜻합니다. 스위프트에서는 print ( ) 함수를 사용하여 콘솔 로그를 출력할 수 있습니다. 
print 함수의 매개변수 타입은 문자열입니다. 그래서 print 함수의 전달인자로 문자열을 전달해 주어야합니다. 기본적으로 print("Hello Swift!")와 같이 사용하면 디버깅 콘솔에서 ‘Hello Swift!’라는 로그를 디버깅 콘솔에서 확인할 수 있습니다. print 함수는 로그를 출력한 뒤에 줄바꿈을 해주기 위해 줄바꿈 문자(\n) 를 자동으로 삽입해줍니다.

콘솔 로그의 print 함수에 대한 이해가 잘 가지 않는다면 다음 포스팅에 이어질 함수의 내용을 참고하세요. 



문자열 보간법(String Interpolation)은 변수 또는 상수 등의 값을 문자열 내에 나타내고 싶을 때 사용합니다. 문자열 내에 \(변수나 상수) 의 형태로 표기하면 이 변수나 상수를 문자열로 치환해서 넣어줍니다. 



기본 데이터 타입

스위프트에서 기본으로 제공하는 데이터 타입(자료형)에 대해 알아보겠습니다. 


Int와 UInt 

정수 타입입니다. Int는 +, - 부호를 포함한 정수를 뜻하며 이 중 - 부호를 포함하지 않고 0 을 포함한 양의 정수는 UInt로 표현합니다. Int와 UInt형의 최댓값과 최솟값은 각각 max 와 min 프로퍼티로 알아볼 수 있습니다. Int와 UInt는 각각 8비트, 16비트, 32비트, 64비 트의 형태를 가지고 있습니다.


var integer: Int = -100 let unsignedInteger: UInt = 50 // UInt 타입에는 음수 값을 할당할 수 없습니다. print("integer 값 : \(integer), unsignedInteger 값 : \(unsignedInteger)") print("Int 최댓값 : \(Int.max), Int 최솟값 : \(Int.min)") print("UInt 최댓값 : \(UInt.max), UInt 최솟값 : \(UInt.min)") let largeInteger: Int64 = Int64.max let smallUnsignedInteger: UInt8 = UInt8.max print("Int64 최댓값 : \(largeInteger), UInt8 최댓값 : \(smallUnsignedInteger)") let tooLarge: Int = Int.max + 1 // Int의 표현 범위를 초과하므로 오류를 냅니다. let cannotBeNegetive: UInt = -5 // UInt는 음수가 될 수 없으므로 오류를 냅니다. integer = unsignedInteger // 오류! 스위프트에서 Int와 UInt는 다른 타입입니다. integer = Int(unsignedInteger) // Int 타입의 값으로 할당해주어야 합니다.


[플레이그라운드 실행결과]




Bool 

Bool은 불리언 타입입니다. 불리언 타입은 참(true) 또는 거짓(false)만 값으로 가집니다. 

let boolean: Bool = true
let iLoveYou: Bool = true
let isTimeUnlimited: Bool = false
print("시간은 무한합니까? : \(isTimeUnlimited)")


[플레이그라운드 실행결과]



Float과 Double 

Float과 Double은 부동소수점을 사용하는 실수형이며 부동소수 타입이라고 합니다. 흔히 우리가 말하는 소수점 자리가 있는 수입니다. 부동소수 타입은 정수형보다 훨씬 넓은 범위의 수를 표현할 수 있습니다. 스위프트에는 64비트의 부동소수 표현을 하는 Double과 32비트의 부동소수 표현을 하는 Float이 있습니다. 
64비트 환경에서 Double은 최소 15자리의 십진수를 표현할 수 있는 반면에 Float은 6자리의 숫자까지만 표현이 가능합니다. 필요에 따라 둘 중 하나를 선택하여 사용할 텐데 무엇을 사용해야 할지 잘 모르는 상황이라면 Double을 사용하길 권합니다.

var floatValue: Float = 1234567890.1 
// Float이 수용할 수 있는 범위를 넘어섭니다. 
// 자신이 감당할 수 있는 만큼만 남기므로 정확도가 떨어집니다.

let doubleValue: Double = 1234567890.1 // Double은 충분히 수용할 수 있습니다. 

floatValue = 123456.1 // Float이 수용할 수 있는 범위의 수로 변경합니다.


Character 

Character는 말 그대로 ‘문자’를 의미합니다. 단어, 문장처럼 문자의 집합이 아닌 단 하나의 문자를 의미합니다. 스위프트는 유니코드 문자를 사용하므로 영어는 물론, 유니코드에서 지원 하는 모든 언어 및 특수기호 등을 사용할 수 있습니다. 문자를 표현하기 위해서는 값의 앞뒤 에 큰따옴표를 사용하여 표현합니다. 

let alphabetA: Character = "A" print(alphabetA) let commandCharacter: Character = “♡" // Character 값에 유니코드 문자를 사용할 수 있습니다. print(commandCharacter) let 한글변수이름: Character = "ᄀ" // 한글도 유니코드 문자에 속해 있으므로 스위프트 코드에 변수 이름으로 사용할 수 있습니다. print("한글의 첫 자음 : \(한글변수이름)")



[플레이그라운드 실행결과]



String 

String은 문자의 나열, 즉 문자열입니다. String은 Character와 마찬가지로 유니코드를 사용할 수 있으며, 값의 앞뒤에 큰따옴표를 사용하여 표현합니다. 


let name: String = "yagom" // 상수로 선언된 문자열은 변경이 불가능합니다. // 이니셜라이저를 사용하여 빈 문자열을 생성할 수 있습니다. // var 키워드를 사용하여 변수를 생성하였으므로 문자열의 수정 및 변경이 가능합니다. var introduce: String = String() introduce.append("제 이름은") // append() 메서드를 사용하여 문자열을 이어붙일 수 있습니다. introduce = introduce + " " + name + "입니다." // + 연산자를 통해서도 문자열을 이어붙일 수 있습니다. print(introduce)




[플레이그라운드 실행결과]



이번에 스위프트의 기초적인 문법과 데이터 타입에 대해 알아봤습니다. 다음 포스팅에서는 컬렉션 타입과 함수에 대해 알아보겠습니다. 

다음 번에 또 뵈어요~ 고맙습니다 :D





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/

twitter : http://www.twitter.com/yagomSoft ( @yagomsoft )

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   









저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

스위프트 시작하기  (0) 2017.05.08
Swift - 프로토콜, 익스텐션  (0) 2017.03.07
Swift - 구조체 클래스  (0) 2017.02.28
Swift - 함수, 콜렉션 타입  (0) 2017.02.06
Swift 기초문법 - 변수, 상수, 기초 데이터 타입  (0) 2017.01.25
Swift란 어떤 언어인가?  (0) 2017.01.23
Posted by yagom


티스토리 툴바