블로그 이미지
Peter Note
Web & LLM FullStacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2014. 11. 26. 12:30 Languages/Go

애플의 새로운 언어인 스위프트(Swift)를 배워보자. 



배경


  - 안드로이드에 빼앗긴 시장을 다시 탈환하기 위한 새로운 언어 

  - Object-C의 굴레에서 벗어나 누구나 쉽게 접근할 수 있게 하고 싶다. 

  - 2014년 6월 2일 Apple WWDC 발표이후 2014년 11월까지 문법의 20%까지 바뀌었다. (Swift GM 정식 버전이 나옴)

  - 레퍼런스 북을 보자 




개념


  - Fast 빠르다 : LLVM 컴파일러 코드 분석기를 이용하여 컴파일과 최적화를 수행

  - Cocoa Framework 접근 : Mac - Cocoa Framework, iOS - Cocoa Touch Framework 접근 가능

  - Safe 안전하다

    + 자료형 자동 추론 및 안정성 증가 : try~catch 구문이 없다 

    + 포인터에 대한 직접 접근 제한

    + ARC(Automatic Reference Counting)를 사용한 메모리 관리 자동화 (OS X 10.7, IOS 5 버전 이상부터 ARC full feature 사용가능)

  - Modern

   + 파이썬 언어에 기반한 읽고 쓰기 쉬운 문법

   + 디버깅, 유지보스에 쉬운 코드 사용 (코코아 펑션은 옆으로 너무 길다)

  - Interactive

   + Xcode 6 의 playground에서 코드 작성하면서 결과 확인이 가능 

  - Unified

   + Swift <-> Object-C 간의 연계 가능 




문법 특징 


  - 컴파일언어가 아닌 스크립트 언어

  - 데이터 타입에 대한 구분이 엄격 : 변수, 상수 선언시 타입입이 결정

  - 엔트리 포인트가 없음 (Java의 main 같은 것이 없다)

  - 세미 콜론이 필요없음 (붙여도 무방)

  - 변수의 시작은 소문자, 클래스의 시작은 대문자로 하자 (대소문자 구분)

  - 문자 하나던 문자열든 더블 쿼팅 (이중 따옴표)를 사용한다

  - import를 사용해 라이브러리를 호출 (Node.js의 require와 유사)




Playground


  - Swift 언어 전용의 프로토타입용 코드 작성툴

  - 처리결과의 stack 확인 가능 (코딩 영역과 스택 영역 존재)




문법


  - 변수 선언 var, 상수 선언 let (상수 변경 불가 및 선언과 동시 초기화)

var addr = "과천시"

var zip : String

zip = "040-234"


let name = "Peter Yun"


단, 클래스의 인터턴스 상수일 경우 선언과 초기화 분리가능 

class ConstTest {

   let name : String = "hi"

}

   또는 

class ConstTest {

    let name : String

    init() {

        name = "Peter"

    }

}


  - 이름은 대소문자 구분, 첫자 숫자 안됨

  - 변수, 상수던 초기화 값에 따라 타입이 결정됨 (타입 추론 : Type Infer)

  - 선언과 초기화가 분리 될때는 타입 선언이 필요 (타입 어노테이션 : Type Annotation)

var name = "Peter"


// 타입 어노테이션

// var 변수명 : 데이터 타입

// 또는

// var 변수명 : 테이터 타입 = 값

var addr : String

addr = "Korea Seoul"


  - 타입 : Int, UInt / Float, Double / String(문자열형) / Character(문자형) / Bool

// 문자열형을 문자형으로 출력 

let str = "This is type"

for char in str {

    println(char)

}


  - "\(변수 또는 상수명)" 문자열에 포함 가능 및 expression 연산 가능  

let name = "Peter"

let str = "Hi \(name)"


// expression

let birthYear = 1980

let nowYear = 2014

let age = "My age is \(nowYear - birthYear + 1)"


let str02 = "1+2+3 = \(1+2+3)"


  - 단항, 이항, 비교, 논리 연산자 

// != 양쪽 띄워쓰기 안하면 오류 발생

var a = 20

var b = 30

println(a!=b)


  - 닫힌 범위 연산자 (Closed range operator) :  세개 점으로 표현  예) 1...5    (1,2,3,4,5)

  - 반닫힘 범위 연산자 (Half-closed range operator) :  두개 점과 <로 표현 예) 1..<5  (1,2,3,4), 배열 순회시 사용함 

let a=1

let b=5


for row in a...b {

    println(row)

}


for row in a..<b {

    println(row)

}


  - 집합 자료형 : 다수 개의 관련된 데이터를 묶음으로 관리할 수 있는 자료형

    + 배열 : Array

    + 튜플

    + 딕셔너리 : Dictionary




배열 


  - 배열 순회

var peter = ["hi", "peter", "yun"]

peter.append("Korea")


for(var i=0 ; i<peter.count ; i++) {

    println("\(i) 번째 \(peter[i]) 이것이다." )

}


for i in 0..<peter.count {

    println("\(i) 번째 \(peter[i]) 이것이다." )

}


for row in peter {

    println("element \(row) 입니다.")

}


  - 배열 선언 및 초기화 

    + Array<> 제너릭(Generic)을 사용함 

    + insert, append를 통해 확장함 

    + Array(count: 10, repeatedValue : "default") 형식으로 인덱스 개수 확보 

// 선언 

var 배열변수명 : Array<배열원소타입>

var 배열변수명 : [배열원소타입]


// 초기화 

var 배열변수명 = Array<배열원소타입>()

var 배열변수명 = [배열원소타입]()


// 선언 + 초기화 

var 배열변수명 : Array<배열원소타입> = Array<배열원소타입>()

var 배열변수명 : [배열원소타입] = [배열원소타입]()


// 예) 

var m : Array<String>

m = Array()


m.append("hi")

m.append("Peter")

m[2] = "zzz"  // error : 인덱스가 확보되지 않았기 때문 

println(m)


var n = [String]()

n.append("hi")

n.append("pp")

println(n)


var c = Array(count: 10, repeatedValue: "dd")

c[0] = "hi"

c[1] = "peter"

c[9] = "zzz"

println(c)


  - Array : 스위프트 자료형, NSArray/NSMutableArray : 파운데이션 프레임워크 자료형 




튜플


  - 집합 자료형 : 순서가 존재하지 않으며 (for 구문 순회할 수 없다는 의미), 이형 데이터를 모두 저장할 수 있는 집합 자료형 

  - () 기호속에 나열해 정의한다 예) ("A", 3, 15.5, true)

var tuple = ("hi", "peter", 35, true)


tuple.0

tuple.1

tuple.2

tuple.3


let (a, b, c, d) = tuple


  - 튜플은 함수에서 많이 사용한다 

func getT() -> (String, String, Bool) {

    return ("hi", "peter", true)

}


  - 딕셔너리 : 키/값을 사용

let cap = ["kr":"seoul", "us":"washington"]


cap["kr"]!  / "seoul"

cap["kr"]   / {Some "seoul"}


또는 


var cap2 : Dictionary<String, String>

cap2 = ["kr":"seoul", "us":"washington"]


cap["kr"]!

cap["kr"]


또는 


var cap3 : [String: String]

cap3 = ["kr":"seoul", "us":"washington"]


cap3["kr"]!

cap3["kr"]


  - 딕셔너리는 순회할 수 있다. 단, 순회시에 튜플 형태로 순회한다. 

for row in cap3 {

    let (key, value) = row

    println("\(key) = \(value)")

}


또는 


for (key, value) in cap3 {

    println("\(key) = \(value)")

}


  - 딕셔너리 값 수정 : updateValue:forKey

cap3.updateValue("SEOUL", forKey: "kr")   // 값 Optional("seoul") 반환 


cap3["kr"]!


  - ! 느낌표의 의미 : 옵셔널,  Optional("seoul") 을 "seoul" 로 변환 - 딕셔너리의 참조 




옵셔널 


  - 오류가 발생할 가능성이 있는 값 예) "hi".toInt() 일때 에러가 있을만한 것은 Optional로 랩핑해서 반환함

    + 모든 것에 대해 랩핑해 버림 

    + Optional()

"123".toInt()  ==> {Some 123}


  - 옵셔널 만들기 : 선언시 타입뒤에 ? 를 붙이면 Optional로 랩핑하여 반환함 

    + nil 이거나 정상값 

    + 느낌표 ! 는 옵션널 랩핑된 것을 벗겨내고 값을 표현할 때  사용한다 (옵셔널 강제 해제)

    + 딕셔너리의 경우 cap["key"] 의 경우 값이 nil일 수 있으므로 Optional 처리가 자동처리된다. 따라서 값을 얻을 때 cap["kr"]! 를 해줌.

var optInt : Int? 

var optStr : String?


var optStr : String?    ===> nil

optStr = "hi"              ===> {Some "hi"}


println(optStr)           ===> Optional("hi")

println(optStr!)          ===> "hi"


  - 문자의 경우 ! 사용전에 nil 체크를 해준다 

if optStr != nil {

    optStr!

}




함수 


  - func 키워드 사용

func 함수명 (인자명:타입, 인자명:타입 ... ) -> 반환_타입 {

    실행 내용

    return 반환값 

}




클래스와 구조체


  - Cocoa Touch Framework를 통해 가장 많이 사용하는 것임 

  - class, struct 둘다 첫 문자는 대문자

  - class, struct 둘다 속성 접근은 . (점) 사용 

class CName {

  statemment

}


// 인스턴스화 

var c = CName()


struct SName {

  statement

}


// 인스턴스화 

var s = SName()


  - 클래스 만의 특징

    + 상속이 가능 

    + 타입 캐스팅이 가능 

    + 디시리얼라이즈 통해 자원 해제 가능 

    + 참조 카운팅을 통해 클래스 인스턴스에 하나 이상의 참조 가능 

  - 타입 메서드 : 클래스 소속 메소드  

class Sample {

    func getInstance() -> Int {

        return 50

    }

    class func getClass() -> Int {

        return 100

    }

}


Sample.getClass()

Sample.getInstance()  // 에러 

var s = Sample()

s.getInstance()


  - init() 클래스의 생성자, 상속, override (재정의. 단, 중복정의는 안됨)

class NamedShape {

    var numberOfSides : Int = 0

    var name: String

    

    // 생성자 

    init(name:String) {

        self.name = name

    }

    

    func simpleDescription() -> String {

        return "A shape \(numberOfSides)"

    }

}


// 상속 

class Square: NamedShape {

    var sideLength: Double

    

    init(sideLength: Double, name: String) {

        self.sideLength = sideLength

        // 부모 생성자 호출 

        super.init(name: name)

        numberOfSides = 4

    }

    

    func area() -> Double {

        return sideLength * sideLength

    }

    

    // 재정의의

    override func simpleDescription() -> String {

        return "A square with sides of length \(sideLength)"

    }

}


// 인스턴스 사용 

let test = Square(sideLength: 5.2, name: "hi dowon")

test.area()

test.simpleDescription()

test.name




UIKit Framework 


  - 앱을 만들기 위해 반드시 사용하는 프레임워크 

  - NSObject 상속




참조 


  - ARC wikipedia


'Languages > Go' 카테고리의 다른 글

[Swift] 스위프트 배우기 - 2일차  (0) 2014.11.27
posted by Peter Note