[C/C++] C 언어 포스트 목록

언어로그/C/C++ 2015. 8. 30. 14:19

[swift2] Xcode7 beta6 Swift 언어 변경사항

Swift 2015. 8. 27. 01:48


Swift Language Enhancements and Changes


1. try? 키워드가 추가되었습니다.

  • try? 구문은 에러를 던질수도 있는 연산을 수행합니다.
  • 연산이 성공하면 결과는 optional로 랩핑되어 반환되고, 에러가 throw 되면 결과는 nil를 반환하고 error는 버려집니다.
  • try?는 if let과 guard 문과 함께 사용될 때 특히 유용합니다.
    func produceGizmoUsingTechnology() throws -> Gizmo { … }
    func produceGizmoUsingMagic() throws -> Gizmo { … }

    if let result = try? produceGizmoUsingTechnology() { return result }
    if let result = try? produceGizmoUsingMagic() { return result }
    print("warning: failed to produce a Gizmo in any way")
    return nil
  • try?에 의해 평가되는 표현식의 결과타입에 항상 optional이 추가된다는 것을 주목하세요.
  • throwing 함수의 반환타입이 Int?이면, try?와 함께 함수를 호출한 결과는 Int?? 또는 'Optional<Optional>' 이 됩니다.


2. Xcode는 . 문법을 사용할 때, 문맥을 인식한 enum 엘리먼트와 option sets의 코드완성 기능을 제공합니다.


3. 프로토콜 extension Static 계산속성을 정의할 수 있습니다.


4. 함수 또는 생성자 파라미터 리스트 어떤 위치에도 가변인자가 올 수 있습니다.

func doSomethingToValues(values: Int..., options: MyOptions = [], fn: (Int) ->
Void) { 
    // function body 
}


5. Objective-C와 호환되지 않는 타입을 포함하는 컬렉션은 더이상 Objective-C 호환타입으로 간주되지 않습니다.

  • 이전에는 Array 구문은 @objc가 마킹된 프로퍼티로 허용되었지만, 그러한 케이스는 더이상 허용되지 않습니다.


6. C typdefs으로 선언된 block은 이제 Swift 클로져 typealias로 임포트됩니다.

  • BOOL 타입 파라미터가 사용된 typedefs 블럭은 Bool 타입 파라미터를 가진 클로져로 임포트됩니다.(이전 베타5에서는 ObjCBool 파리미터로 되었음.)
  • 이것은 블럭 파라미터의 행동과 임포트된 Objective-C 메서드를 매칭시킵니다.


7. 타입체커가 생성한 에러메시지는 구체적이고 유용하게 개선되고 있습니다.

  • 진단시에, type alias를 사용했다면 별칭(aka)을 출력합니다.


Swift Standard Library Enhancements and Changes


1. print()와 debugPrint()가 개선되었습니다.

  • 가변인자 지원하여, 한번의 호출로 여러개의 아이템을 출력할수 있습니다.
  • separator: String = " " 가 추가되어, 어떻게 아이템이 구분되는지 제어할 수 있습니다.
  • appendNewline:bool = true 는 terminator:String = "\n"로 교체되었습니다.
  • output stream을 인자로 받는 print 함수에는 stream 인자에 toStream 레이블을 추가했습니다.


2. RangeReplaceableCollectionType.extend() 메소드가 appendContentsOf()로 이름이 변경되었습니다.

  • splice() 메서드는 insertContentsOf()로 이름이 변경되었습니다.


3. 클로져와 @autoclosure 인자를 갖는 대부분의 표준라이브러리 API은 이제 rethrows를 사용합니다.

  • map과 filter 같은 메서드의 클로져 파라미터들이 에러를 throw할 수 있게 허용합니다.
  • 에러를 발생시킬 수 있는 표현식과 &&, ||, ?? 같은 short-circuiting 연산자를 함께 사용할수 있습니다.


4. 모든 CollectionType은 이제 sliceable 합니다.

  • 다음 sequence spllitting/slicing 함수들은 SequenceType 프로토콜 요구사항에 맞게 삭제되거나 프로토콜 extension 디폴트 구현으로 대체되었습니다.
/// Returns the first `maxLength` elements of `self`,
/// or all the elements if `self` has fewer than `maxLength` elements.
prefix(maxLength: Int) -> SubSequence

/// Returns the last `maxLength` elements of `self`,
/// or all the elements if `self` has fewer than `maxLength` elements.
suffix(maxLength: Int) -> SubSequence

/// Returns all but the first `n` elements of `self`.
dropFirst(n: Int) -> SubSequence

/// Returns all but the last `n` elements of `self`.
dropLast(n: Int) -> SubSequence

/// Returns the maximal `SubSequence`s of `self`, in order, that
/// don't contain elements satisfying the predicate `isSeparator`.
split(maxSplits maxSplits: Int, allowEmptySlices: Bool, @noescape isSeparator:
(Generator.Element) -> Bool) -> [SubSequence]
  • split를 위해 다음 convenience extension을 제공합니다.
split(separator: Generator.Element, maxSplit: Int, allowEmptySlices: Bool) ->
[SubSequence]  
  • 또한 새로운 프로토콜 요구사항과 컬렉션 타입의 디폴트 구현이 사용가능합니다.
/// Returns `self[startIndex..<end]`
prefixUpTo(end: Index) -> SubSequence

/// Returns `self[start..<endIndex]`
suffixFrom(start: Index) -> SubSequence

/// Returns `prefixUpTo(position.successor())`
prefixThrough(position: Index) -> SubSequence





[iOS] 익스텐션 (Extension)

아이폰 2015. 8. 18. 21:12

1. iOS 익스텐션 개요

  • 익스텐션은 애플리케이션의 특정기능을 다른 애플리케이션에서 사용될 수 있게 하기 위해 설계된 iOS8의 한 부분.
  • 익스텐션의 목적은 특정 기능을 다른 애플리케이션에서 접근할 수 있도록 하는 것.


2. 익스텐션 타입

  • iOS는 익스텐션 포인트(extension point)로 지시되는 익스텐션 타입을 제공.
  • 익스텐션 포인트는 익스텐션이 구현될 수 있도록 공개한 iOS 운영체제의 영역.


1. 투데이 익스텐션(Today Extension)

  • iOS 알림센터의 Today 화면에서 사용할 수 있는 익스텐션.
  • 디폴트로 캘린더 정보와 우세한 주식가격 정보를 표시.
  • 사용자에게 정보를 표시하는 위젯형태를 취함.



2. 쉐어 익스텐션(Share Extension)

  • 소셜 네트워크 사이트 또는 컨텐츠 공유 서비스의 호스트앱에서 이미지, 비디오, 텍스트, 웹사이트 등의 컨텐츠를 공유하기 위한 빠른 접근 매커니즘 제공.
  • 쉐어 익스텐션은 사용자가 호스트앱에서 공유버튼을 눌렀을 때 표시되는 액티비티 뷰 컨트롤러 패널에 표시됨.
  • 컨텐츠 포스팅을 위한 인터페이스 구현을 위해 SLComposeServiceViewController클래스 이용.
  • SLComposeServiceViewController는 UI 커스터마이징이 가능하며, 포스팅하기 전에 수정할수 있는 기능을 제공.



3. 액션 익스텐션(Action Extension)

  • 호스트 앱 내의 컨텐츠가 다른 식으로 변형되거나 보여지도록 만듬.
  • 쉐어 익스텐션처럼 공유버튼을 통해 액티비티 뷰 컨트롤러로 접근.
  • 호스트앱의 콘텐츠 타입을 지원하는 액션 익스텐션만 옵션으로 표시됨.



4. 포토 에디팅(Photo Editing Extension)

  • 애플리케이션의 사진 편집 기능을 내장된 iOS 사진 앱 내에서 접근할 수 있도록 해줌.
  • 사진앱에서 이미지 선택후 편집 옵션을 선택한 다음 ... 버튼을 탭할 때 표시됨.



5. 도큐먼트 익스텐션(Document Extension)

  • 다른 애플리케이션이 디바이스에서 실행되는 동안 (익스텐션을) 포함하는 앱이 문서 저장소처럼 동작하도록 함.
  • Document Picker ViewController 익스텐션과 File Provider 익스텐션으로 구성됨.
  • Document Picker ViewController 익스텐션은 문서들을 검색하거나 선택할 수 있는 사용자 인터페이스를 제공함.
  • File Provider 익스텐션은 호스트앱이 앱의 샌드박스 외부에 있는 문서에 접근할 수 있도록 해줌.
  • 포함하는 앱에서 저장된 문서를 이동하거나 여는 작업을 지원해야 한다면 파일 프로파이더 익스텐션이 필요함.



6. 커스텀 키보드 익스텐션(Custom Keyboard Extension)

  • iOS 디바이스에 커스텀 키보드를 생성하고 설치할 수 있도록 함.
  • 디바이스의 모든 애플리케이션에서 사용될수 있음.
  • 설정앱의 키보드 설정에서 선택할수 있음.




[swift2] Xcode7 beta5 Swift 언어 변경사항

Swift 2015. 8. 14. 02:14


Linker

  • bitcode를 활성화하면 이제 weak frameworks와 weak libraries가 지원됩니다. linker는 더이상 -weak_framework, -weak-l 또는 -weak_librarys가 -bitcode_bundle 과 함께 사용될수 없다고 경고하지 않습니다.


Swift Language Changes

1. 구조체, 클래스도 이제 ErrorType 프로토콜을 구현할수 있습니다.


2. 실패가능한 initializer에 위임하거나 체이닝할 때 !를 사용하여 force-unwrap 할 수 있습니다.

  • self.init(...) 또는 super.init(...)가 실패가능한 경우 아래코드와 같이 force-unwrap 할 수 있습니다.
extension UIImage {
    enum AssetIdentifier: String {
        case Isabella
        case William
        case Olivia
    }
    convenience init(assetIdentifier: AssetIdentifier) {
        self.init(named: assetIdentifier.rawValue)!
    }
} 
  • 위와같이 실패가능한 initializer에 체이닝한 non-optional initializer 정의가 가능해집니다.


3. 성능향샹을 위한 -Onone 빌드 옵션

  • -Onone 옵션 (debug) 빌드를 사용하면 표준라이브러리 제네릭 타입에 특화된 인스턴스를 사용하여 빌드성능을 향상시킬 수 있습니다.
  • 많은 경우에 컴파일 타임에 영향없이 debug 빌드에서 상당히 빠른 실행파일을 생성합니다.


4. Objective-C 클래스의 제네릭 서브클래스와 이것을 상속하는 non-제네릭 클래스들은 runtime metadata 인스턴스화가 요구됩니다.

  • Objective-C 코드에서 직접적으로 네이밍을 지정할수 없습니다.
  • Beta4에 Objective-C 클래스들의 제네릭 서브클래스 정의가 가능해졌지만, 생성된 Objective-C 브리징 헤더에는 그러한 클래스들을 에러항목으로 리스팅합니다. 이로인해 잘못된 런타임 행동과 컴파일 타임에러를 발생시키는 오류를 수정하였습니다.
  • 클래스에 대한 @objc 속성의 행동이 좀더 명확해졌습니다.
  • 브리징헤더에 나타날 수 없는 클래스에 @objc를 적용하면 이제 에러입니다.
  • 클래스의 어떤 수퍼클래스라도 @objc 클래스라면, 그 클래스의 멤버들은 암묵적으로@objc 이며, 모든 @objc 클래스들은 NSObject 를 상속해야함. 따라서 유효한 코드에 대한 어떤 변경을 발생시키지는 않습니다.


5. MacTypes.h 에 정의된 Boolean은 Swift와 Objective-C 타입 브리징 상황에서 Bool로 임포트됩니다.


6. NSManaged 속성을 CoreData가 자동생성한 키밸류코딩 호환 to-many 접근자에 접근하기 위한 메서드와 프로퍼티에 사용할 수 있습니다.

@NSManaged var employees: NSSet

@NSManaged func addEmployeesObject(employee: Employee)
@NSManaged func removeEmployeesObject(employee: Employee)
@NSManaged func addEmployees(employees: NSSet)
@NSManaged func removeEmployees(employees: NSSet)
  • 이것들은 NSManagedObject 서브클래스에 선언되어야 합니다.


7. 타입 이름들과 enum cases들은 이제 디폴트로 자격없이(프로토콜 구현없이) print하고 String으로 변환할수 있습니다. debugPrint와 String(refelcting:)은 fully-qualified 이름을 얻기 위해 사용할 수 있습니다.

enum Fruit { case Apple, Banana, Strawberry }
print(Fruit.Apple)           // "Apple"
debugPrint(Fruit.Apple)      // "Fruit.Apple"


8. print()와 Mirrors의한 reflection은 current case와 멀티 payload 타입을 갖는 모든 enums payload를 report 할수 있습니다.

  • 유일하게 reflection이 지원되지 않고 남아있는 enum 타입들은 @objc enums와 C에서 임포트된 enums 입니다.


Swift Standard Library Enhancements and Changes

1. SequenceType 프로토콜 구현체에 .forEach 구문을 사용할 수 있습니다.

(0..<10).forEach {
    print($0)
}    

위 구문은 아래구문과 유사합니다.


for x in 0..<10 {
    print(x)
}

하지만 다음과 같은 차이점이 있습니다.

  • for-in 루프문과 다르게 break, continute를 사용하여 현재 클로져 몸체 호출을 종료하거나 일련의 호출을 건너뛸수
    없습니다.

  • 클로져 몸체에 return문을 사용하면 외부 스콥이 아닌 현재 호출만 종료할수 있으며, 이어지는 일련의 호출을 건너뛸수 없습니다.

  • 이러한 제약때문에 forEach 멤버는 함수형 알고리즘에 일련의 체이닝을 적용하고, 몸체가 적을때만 사용하도록 권장합니다.

foo.map {...}.filter {...}.forEach {...}
  • 다른 경우에는 for..in 문 사용을 권장합니다.


3. SIMD: simd 모듈의 정수형 벡터타입은 &+, &-, & 연산자를 사용하여 감싸진 unchecked 산술식만 지원합니다. +,-, 연산자들은 정수형 벡터에는 사용 불가능하고 Xcode가 자동으로 wrapping 연산자로 교체하라고 제안할 것입니다.


4. SIMD: smid 모듈의 정수형 벡터타입 코드생성은 벡터하드웨어를 더 잘 사용할 수 있도록 개선되어 대부분의 경우에 극적으로 성능이 향상되었습니다.


5. Dictionary의 removeAtIndex(_:) 메서드는 key,value 쌍을 제거하여 두 엘리먼트를 튜플로 반환합니다.

  • 유사하게 Set의 removeAtIndex(_:)은 삭제된 엘리멘트를 반환합니다.


6. Word와 UWord 타입은 표준라이브러리에서 삭제되었습니다. 대신 UInt를 사용하세요.




[swift1.2] Swift 프로토콜 지향 프로그래밍

Swift 2015. 8. 6. 00:57



WWDC 2015 세션중 "Protocol-Oriented Programming in Swift" 라는 흥미로운 세션이 있습니다. 애플에서 Standard Library 그룹의 리더를 맡고 있는 Dave Abrahams 라는 분이 발표한 세션입니다. 세션에서 제공하는 슬라이드와 InfoQ에서 이 세션을 정리한 아티클을 바탕으로 내용을 요약했습니다.


클래스는 멋집니다!


다음과 같은 멋진 특징들을 제공하지요.

  • 캡슐화 (Encapsulation)
  • 접근제어 (Access Cotrol)
  • 추상화 (Abstraction)
  • 네임스페이스 (Namespace)
  • 풍부한 문법 (Epressive Syntax)
  • 확장성 (Extensibility)

그런데...


구조체로도 다 할수 있습니다.

클래스는 훌륭합니다. 타입은 훌륭합니다!

사실 위 특징들은 모든 타입들의 특징이며 클래스는 그것을 구현하는 하나의 방법에 불과합니다. 그렇다면 클래스 사용으로 인한 단점은 무엇이 있을까요?


1. 암묵적인 참조(Reference) 공유

  • 두 객체가 동시에 어떤 객체를 참조하는 경우, 서로 그 사실을 모른채 그 객체를 변경할 수 있습니다.
  • 참조 공유를 방지하기 위해 참조하는 객체를 복사할 수 있지만, 그렇게 하면 효율성이 나빠집니다.
  • 참조를 공유하는 객체에 Race Conditions 이 발생할 수도 있습니다.
  • Lock을 사용하여 레이스 컨디션을 방지할수 있지만 효율성은 더 나빠집니다.
  • Lock을 잘못 사용하면 Deadlock 상태에 빠질 수 있습니다.
  • 잦은 Lock 사용은 코드를 복잡하게 합니다.
  • 복잡성은 더 많은 버그를 유발합니다.

Values Don't Share. (That's a good thing)


2. 상속 (비지니스에 관한 모든 것을 가지고 있습니다.)

  • 슈퍼 클래스를 하나 밖에 가질수 없기 때문에, 초기에 잘 선택해야합니다.
  • 슈퍼 클래스를 나중에 변경하는 것은 매우 어렵습니다.
  • 슈퍼클래스가 갖는 모든 저장속성은 서브클래스에도 (강제적으로) 상속됩니다.
  • 초기화 처리가 복잡해집니다.
  • 수퍼클래스의 불변성을 깨뜨리지 않을수 없게됩니다.
  • 언제 무엇을, 어떻게 재정의해야 하는지 (수퍼 클래스에 대해서)알아야 합니다.

More and more, we promote delegation.


3. 타입관계를 잃어버립니다.(Lost Type Relationships.)

  • 추상 수퍼클래스와 서브클래스의 구현코드가 함께 존재하게 됩니다.
  • 서브클래스 메소드에 접근하기 위해 수퍼클래스를  서브클래스로 다운캐스팅하면서 타입관계를 잃게됩니다.

  • 이진탐색 클래스 모델 Ordered 정의

class Ordered {
    func precedes(other: Ordered) -> Bool { fatalError("메소드를 구현해주세요.") }
}

class Number:Ordered {
    var value:Double = 0
    override func precedes(other: Ordered) -> Bool {
        return value < (other as! Number).value // 
    }
}  

func binarySearch(sortedKeys: [Ordered], forkey k: Ordered) -> Int {
    var lo = 0
    var hi = sortedKeys.count
    while hi > lo {
        let mid = lo + (hi - lo) / 2
        if sortedKeys[mid].precedes(k) { lo = mid + 1 }
        else { hi = mid }
    }
    return lo
}

as! ASubclass 는 타입 관계를 잃어버렸다는 신호
대부분 추상화를 위해 클래스를 사용하기 때문이다.


4. 좋은 추상화 메커니즘이란?

  • Value type을 지원합니다.(클래스 외에도)
  • 정적 타입관계를 지원합니다. (동적 디스패치 외에도)
  • 큰 덩어리로 뭉치지 않아야합니다.
  • Retroactive 모델링을 지원합니다.
  • 모델에 인스턴스 데이터를 강요하지 않아야 합니다.
  • 모델에 초기화의 부담이 없어야 합니다.
  • 무엇을 구현해야 하는지 명확해야 합니다.

Swift는 프로토콜 지향 프로그래밍 언어!


5. 프로토콜 지향 프로그래밍

  • Swift에서 새롭게 추상화를 생각할 때 첫 번째 포인트는 프로토콜!

이진탐색 프로토콜 모델 Ordered 변경해보겠습니다.
protocol Ordered {
    func precedes(other:Self) -> Bool
}    

struct Number : Ordered {
    var value:Double = 0
    func precedes(other:Number) -> Bool {
        return self.value < other.value 
    }
}

이진탐색 함수를 정의합니다.
func binarySearch<T:Ordered>(sortedKeys:[T], forKey k: T) -> Int {
    var lo = 0
    var hi = sortedKeys.count
    while hi > lo {
        let mid = lo + (hi-lo)/2 
        if sortedKeys[mid].precedes(k) { lo = mid + 1 }
        else { hi = mid }
    }
    return lo
}

Int 배열에 이진탐색 함수를 적용해 보겠습니다.
  • 먼저 Int가 프로토콜 Ordered를 구현해야합니다.
// Int형 Ordered 프로토콜 구현하기 

extension Int:Ordered {
    func precedes(other: Int) -> Bool {
        return self < other
    }
}
  • Int 배열에 이진탐색을 적용합니다.
// 1. 키 정렬 
var keys = [10, 30, 1, 4, 5, 6, 7, 8, 55, 20]
var sortedKeys = keys.sorted {  $0 < $1 }
// sortedKeys: [1, 4, 5, 6, 7, 8, 10, 20, 30, 55]

// 2. 찾을 키
var searchKey = 30
// 키 30의 index는 8.

// 3. 이진탐색 
var searchIndex = binarySearch(sortedKeys, forkey: searchKey)
// searchIndex: 8
Number 배열에도 이진탐색을 적용해보겠습니다.
// 1. 정렬된 Number 배열 생성  
var numbers = sortedKeys.map { return Number(value: Double($0)) }
// numbers: [1.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0, 20.0, 30.0, 55.0]

// 2. 찾을 키
var keyToSearch = 5.0

// 3. 이진탐색
var index = binarySearch(numbers, forkey: Number(value: keyToSearch))
// index: 2

프로토콜을 사용하면, 커스텀 Number 구조체 뿐만 아니라 기존 타입에도 이진탐색을 쉽게 적용할 수 있음을 알 수 있습니다.




[swift] 문자열과 문자 -1 (Strings and Characters)

Swift 2015. 8. 1. 21:45

프래그램밍에서 기본은 문자열 다루기! Swift에서는 문자열과 문자를 어떻게 다룰까요?

  • 문자열은 "hello" 같은 문자들의 순서집합

  • Swift 문자열은 String 타입으로 표현되며, String 타입은 Character타입 값들의 집합으로 표현됨.

  • String과 Character 타입은 코드에서 텍스트를 다룰 때 빠르고 유니코드 호환되는 방식을 제공.

  • 문자열 생성과 조작 문법은 간단하고 가독성이 좋으며, C와 유사한 문자열 리터럴 문법을 가짐.

  • + 연산자를 사용하여 두 문자열을 쉽게 연결가능.

  • 문자열의 변경가능 유무는 Swift의 다른 값들처럼 var,let 에 따라 관리.

  • 문법이 단순함에 더해 Swift의 문자열 타입은 빠르고 현대적은 구현을 갖음.

  • 모든 문자열은 인코딩에 독립적인 유니코드 문자로 구성.

  • 다양한 유니코드 표현방식으로 문자들 접근을 지원.

  • 문자열 보간을 사용하여 문자열에 상수, 변수, 리터럴, 표현식 삽입가능.


1. 문자열 리터럴

문자열 리터럴은 쌍따옴표 쌍으로 감싸진 고정된 순서의 문자들입니다. 상수나 변수에 초기값으로 문자열 리터럴을 사용할수 있습니다.

let someString = "Some string literal value"  

Swift는 someString 상수가 문자열 리터럴로 초기화 되었기 때문에 String 타입임을 추론합니다.


2. 빈 문자열 생성

var emptyString = ""              // 문자열 리터럴 사용
var anotherEmptyString = String() // 문자열 생성자 사용 
// 두 문자열은 비어있으면 두 표현은 동일함 

isEmpty 속성을 사용해서 String 값이 비어있는지 검사할 수 있습니다.

if emptyString.isEmpty {
    print("Nothing to see here")    
}  


3. 문자열의 수정가능 유무(Mutability)

문자열을 변수(var) 또는 상수(let)에 할당하느냐에 따라 String의 수정가능 유무를 가리킬수 있습니다.

var variableString = "Horse"
variableString += " and carriage"
// variableString은 "Horse and carriage"

let constantString = "Highlander"
costantString += " and another Highlander"
// 문자열 상수는 변경할수 없다는 컴파일 에러가 발생

문자열의 수정가능 유무를 NSString 클래스와 NSMutableString 클래스로 결정하는 Objective-C 와는 접근방식이 다릅니다.


4. 문자열은 Value타입!

Swift의 String타입은 value타입입니다. 새 문자열을 생성하면 문자열은 함수나 메소드에 전달되거나, 변수 또는 상수에 할당될 때마다 복사됩니다. 각 경우에 기존 문자열의 복사본이 생성되고 이 복사본이 전달되거나 할당됩니다.

Swift의 이런 특성(copy-by-default)은 함수나 메소드가 문자열을 전달받으면 어디에서 왔는지에 상관없이 완전히 문자열을 소유한다는 것을 보장해줍니다. 즉 스스로 문자열을 변경하지 않으면 전달받은 문자열은 결코 수정되지 않을 것이라 확실할 수 있습니다.

사실 Swift 컴파일러가 반드시 필요한 경우에만 복사가 일어나도록 문자열 사용을 최적화합니다. value 타입으로 문자열을 사용하면 항상 좋은 성능을 얻을 수 있습니다.


5. 문자 다루기

for-in 루프에서 character 속성을 사용해서 문자열의 개별 문자들에 접근할 수 있습니다.

for character in "Dog!".character {
    print(character)
}
// D
// o
// g
// !

한문자만을 갖는 문자열 리터럴을 사용해서 Character 상수를 생성할수 있습니다.

let exclamationMar:Character = "!"  

문자열은 Character의 배열을 생성자의 인자로 전달하여 생성할 수도 있습니다.

let catCharacters:[Character] = ["C", "a", "t", "!"]
let catString = String(catCharacters)
print(catString)
// Cat!


6. 문자열과 문자 접합

  • 연산자를 사용하여 두 문자열을 접합한 새로운 문자열을 생성할 수 있습니다.
let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome은 "hello there"

문자열 변수에 += 연산자를 사용하여 문자열을 추가할 수도 있습니다.

var instruction = "look over"  
instruction += string2
// instruction은 "look over there"

문자열 변수에 append() 메소드를 사용하여 문자를 추가할 수 있습니다.

let exclamationMark:Character = "!"  
welcome.append(exclamationMark)
// welcome은 "hello there!"

Character 변수는 하나의 문자만 포함하기 때문에 다른 문자열이나 문자를 추가할 수 없습니다.


7. 문자열 보간(Interpolation)

문자열 보간은 문자열 리터럴 안에 상수, 변수, 리터럴, 표현식을 혼합하여 새로운 문자열을 생성하는 방식입니다. 각 항목은 백슬러시와 소괄호 안에 감싸여진 문자열 리터럴에 삽입됩니다.

let multiplier = 3  
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"  

위 예에서 multipiler값은 문자열 리터럴 (multiplier)에 삽입됩니다. 새 문자열을 생성하기 위해 문자열 보간이 평가될때 placeholder는 multiplier의 실제값으로 대치됩니다.
표현식 Double(multiplier) * 2.5는 계산된 결과 7.5가 문자열에 삽입됩니다.