The Swift Programming Language - Strings and Characters（文字列型、文字型）をまとめる


[The Swift Programming Language をまとめるトップ](http://qiita.com/kiyotaman/items/052f82e9f93590b79c64)

## Strings and Characters（文字列型、文字型）
**Character** と **String** タイプがある
String は Character の集合
C言語のシンタックスに類似する
可変（mutability）は、**constant** か **variable** 宣言によって決まる
他の値も同様
定数、変数、リテラルなど代入可能

> **NOTE**
> **String型** は NSString のAPIと同じように使える

### String Literals（文字列リテラル）
（""）ダブクオートで直接入力された値を代入する

```swift
let someString = "リテラル文字列"
```

Swift が定数 someString に代入される値を **String** と推論して初期化している

#### 特殊文字

* \0(null), \\(backslash), \t(horizontal tab), \n(line feed), \r(carriage return), \"(double quote) and \'(single quote)
* Single-byte Unicode scalars \xnn -> nn は hexadecimal（16進数）
* Two-byte Unicode scalars \xnnnn -> nnnn は hexadecimal（16進数）
* Four-byte Unicode scalars \xnnnnnnnn -> nnnnnnnn は hexadecimal（16進数）

```swift
let wiseWords = "\"想像力は知力に勝る\" - Einstein"
// "想像力は知力に勝る" - Einstein
let dollarSign = "\x24"        // $,  Unicode scalar U+0024
let blackHeart = "\u2665"      // ♥,  Unicode scalar U+2665
let sparklingHeart = "\U0001F496"  // ?, Unicode scalar U+1F496
```

#### Initializing an Empty String（空文字を初期化）
（""）空のリテラルか String() を使って初期化できる

```switf
var emptyString = "" // 空のリテラル
var anotherEmptyString = String() // イニシャライザー
// 両方ともからの文字列で、等価
```

**isEmpty** を使ってから文字を判定
戻り値は Boolean

```swift
if emptyString.isEmpty {
    println("空文字だよ")
}
// prints "空文字だよ"
```

### String Mutability（可変文字列）
**var** を使って、変数宣言すると可変文字（mutated）になる
**let** を使って、定数として宣言すると編集不可

```swift
var variableString = "Horse"
variableString += " and carriage"
// variableString が "Horse and carriage" になる
 
let constantString = "Highlander"
constantString += " and another Highlander"
// コンパイル時にエラーになる
```

> **NOTE**
> ObjC は NSString と NSMutableString を使っていて、異なる

### Strings Are Value Types（文字列は値）
Swift の **String** は値型
新しい文字列の値を定義する場合、文字列型の値を _コピー_ する
文字列形の変数を定義するたびに、新しく値をコピーする

> **NOTE**
> NSString の場合、リファレンスを代入したり渡したりする
> 明示的に指定しない限り、コピーは代入されない
> Cocoaとでは仕様が違う

パフォーマンスに関しては、Swift が良きにはからってくれるらしい

### Working with Characters（文字型を試す）

```Swift
for character in "Dog!?" {
    println(character)
}
// D
// o
// g
// !
// ?
```

リテラルで一文字をセットする

```swift
let yenSign: Character = "¥"
```

### Counting Characters（文字数のカウント）
**countElements** を使って文字数をカウント

```swift
let unusualMenagerie = "Koala ?, Snail ?, Penguin ?, Dromedary ?"
println("unusualMenagerie は \(countElements(unusualMenagerie)) 文字")
// prints "unusualMenagerie は 40 文字"
```

> **NOTE**
> 数え方が違うので、NSString の lenght と同じ結果じゃない場合がある

### Concatenating Strings and Characters（文字列と文字の結合）
**String** と **Characters** は（+）または (+=）で繋げる事ができる

```swift
let string1 = "hello"
let string2 = " there"
let character1: Character = "!"
let character2: Character = "?"
 
let stringPlusCharacter = string1 + character1        // は "hello!"
let stringPlusString = string1 + string2              // は "hello there"
let characterPlusString = character1 + string1        // は "!hello"
let characterPlusCharacter = character1 + character2  // は "!?"

var instruction = "look over"
instruction += string2
// instruction が "look over there"　になる
 
var welcome = "good morning"
welcome += character1
// welcome が "good morning!" になる
```

> **NOTE**
> **Character型** は一文字しか保持できないので、**Character型** には結合する事はできない

### String Interpolation（文字列改竄：かいざん）
\()を使ってリテラル文字列の中で以下のように書く事ができる

```swift
let multiplier = 3
let message = "\(multiplier) x 2.5 ＝ \(Double(multiplier) * 2.5)"
// message is "3 x 2.5 ＝ 7.5"
```

\(multiplier) は multiplier のプレイスホルダーでその実際の値と置き換えられ文字列として生成される

> **NOTE**
> エスケープしていない（",',\n,\r）は使えない

### Comparing Strings （文字列比較）
三つの比較の方法がある

#### String Equality（文字列等価）

文字列型の値を評価する

```swift
let quotation = "これって同じ？"
let sameQuotation = "これって同じ？"
if quotation == sameQuotation {
    println("同じものとして評価されました")
}
// prints "同じものとして評価されました"
```

### Prefix and Suffix Equality（接頭、接尾等価）
**hasPrefix**　と **hasSuffix**　を使う事ができる
文字列を引数として Boolean を返す

#### 例えば

```swift
let romeoAndJuliet = [
    "Act 1 Scene 1: Verona, A public place",
    "Act 1 Scene 2: Capulet's mansion",
    "Act 1 Scene 3: A room in Capulet's mansion",
    "Act 1 Scene 4: A street outside Capulet's mansion",
    "Act 1 Scene 5: The Great Hall in Capulet's mansion",
    "Act 2 Scene 1: Outside Capulet's mansion",
    "Act 2 Scene 2: Capulet's orchard",
    "Act 2 Scene 3: Outside Friar Lawrence's cell",
    "Act 2 Scene 4: A street in Verona",
    "Act 2 Scene 5: Capulet's mansion",
    "Act 2 Scene 6: Friar Lawrence's cell"
]
```

Act 1 を数えてみる

```swift
var act1SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 1 ") {
        ++act1SceneCount
    }
}
println("Act1 は \(act1SceneCount) です")
// prints "Act1 は 5 です"
```

**hasSuffix** を数えてみる

```swift
var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
    if scene.hasSuffix("Capulet's mansion") {
        ++mansionCount
    } else if scene.hasSuffix("Friar Lawrence's cell") {
        ++cellCount
    }
}
println("\(mansionCount) マンションシーン; \(cellCount) セルシーン")
// prints "6 マンションシーン; 2 セルシーン"

```

### Uppercase and Lowercase Strings（大文字、小文字）
**uppercaseString** と **lowercaseString** が用意されている

```swift
let normal = "Could you help me, please?"
let shouty = normal.uppercaseString
// shouty is equal to "COULD YOU HELP ME, PLEASE?"
let whispered = normal.lowercaseString
// whispered is equal to "could you help me, please?"
```

### Unicode
国際化標準の文字コード
基本的に準拠している
※ここはざっくりまとめる

#### Unicode Terminology
全ての文字が一つもしくは複数のunicodeスカラーで成り立っている
unicode スカラーは21-bitで、 U+0061 が LOWERCASE LATIN LETTER A ("a"), or U+1F425 が FRONT-FACING BABY CHICK ("?").
unicode を何かに書き込むときには、幾つかのUTF-8やUTF16フォーマットに変換する

#### Unicode Representations of Strings
文字列型のプロパティに **utf8**, **utf16**, **unicodeScalars** があって、それを使って操作できる

#### 例えば

```swift
let dogString = "Dog!?" // (犬の絵文字, または Unicode scalar U+1F436):

for codeUnit in dogString.utf8 {
    print("\(codeUnit) ")
}
print("\n")
// 68 111 103 33 240 159 144 182

for codeUnit in dogString.utf16 {
    print("\(codeUnit) ")
}
print("\n")
// 68 111 103 33 55357 56374

for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ")
}
print("\n")
// 68 111 103 33 128054

for scalar in dogString.unicodeScalars {
    println("\(scalar) ")
}
// D
// o
// g
// !
// ?
```