"hello, world"
や "albatross"
のような一連の文字です。Swift の文字列は String
型で表されます。String
の内容には、様々な方法でアクセスすることができます(Character
型の値のコレクションとしてなど)。String
と Character
型は、高速で、Unicode に準拠した方法でテキストを扱うことができます。文字列の生成と操作の構文は、C 言語に似た文字列リテラルの構文を使い、軽量で読みやすくなっています。文字列の連結は、+
演算子を使用して 2 つの文字列の連結をするシンプルなものです。また、文字列が変更が可能かどうかは、他の型と同じように定数か変数かを選択することで管理できます。また、文字列補間と呼ばれるプロセスの中で、定数、変数、リテラルや式をより長い文字列の中に入れることができます。こういった特徴から、表示用、ストレージ用、出力用などにカスタム文字列も簡単に作ることができます。String
型は、高速で、モダンな実装になっています。それぞれの文字は、特定の変換形式とは独立した Unicode 文字群で構成され、様々な Unicode 形式でアクセスできるようになっています。NOTE Swift のString
型は、Foundation のNSString
クラスとスムーズにやりとりできるようにしています。同様に、Foundation でもNSString
で定義されたメソッドを使用できるようにするために、String
を拡張しています。つまり、Foundation をインポートすると、キャストなしでNSString
のメソッドにString
からアクセスできます。 Foundation と Cocoa を使ったString
の使用方法に関しては、Bridging Between String and NSStringを参照ください
String
を_文字列リテラル_として使用することができます。文字列リテラルはダブルクォーテーション("
)で囲まれた一連の文字です。someString
は文字列リテラルで初期化されているので、String
型と推論されていることに注目してください。"
)で囲みます。\
)を書きましょう:"""
)の前に空白を加えると、他の行に存在する同じ位置の空白も無視するようになります。一方で、終了クォーテーションマーク("""
)の空白のさらに後に空白を追加すると、その行の空白_は_含まれるようになります。"""
)よりもさらにインデントを追加しているため、4 つの空白から開始します。\0 (null文字)
、\\ (バックスラッシュ)
、\t (水平タブ)
、\n (ラインフィード)
、\r (キャリッジリターン)
、\" (ダブルクォーテーション)
、\' (シングルクォーテーション)
wiseWords
定数は 2 つのエスケープされたダブルクォーテーションを含んでいます。dollarSign
と blackHeart
と sparklingHeart
定数は、Unicode スカラの例です:"""
を含めたい場合、少なくともその中の 1 つをエスケープしてください。#"Line 1\nLine 2"#
は 2 行の文字列を出力するのではなく、改行コード()を出力します。\
)の後に囲んでいる番号記号と同じ番号記号を、同じ数追加してください。例えば、#"Line 1\nLine 2"#
で、改行したい場合は、#"Line 1\#nLine 2"#
と書くことができます。同様に、###"Line1\###nLine2"###
でも改行することができます。"""
を含めたい場合、文字列を終わらせる記号を変えましょう。例えば:String
のイニシャライザを使用して新しいインスタンスを初期化します。isEmpty
というブール値のプロパティをチェックすることで String
が空文字かどうかを判定できます。String
が変更可能かどうかは、変数(変更可能)か定数(変更不可能)のどちらに設定するかによって示すことができます:NOTE これは Objective-C と Cocoa とは異なります。Objective-C と Cocoa では、変更の可不可を示すために 2 つのクラス(NSString
とNSMutableString
)から選択します。
String
型は_値型_です。新しい String
を生成すると、関数やメソッドのパラメータで渡されるときや、他の定数、変数に代入されるときに、値のコピーが発生します。いずれの場合でも、既存の String
のコピーが生成され、元の値ではなく新しいコピーが渡され(または代入され)ます。値型はStructures and Enumerations Are Value Types(構造体と列挙型は値型)で記載されています。String
の挙動は、String
が関数やメソッドのパラメータで渡されるときに、どこからその値が来たとしても、正しい String
を所有していることが保証されます。つまり、渡された文字列は、自身で変更しない限り決して変更されることがありません。for-in
ループを使用して文字列を繰り返し処理することで、String
の個々の Character
にアクセスすることができます。Character
の型注釈を与えて 1 文字のリテラルから Character
型の定数や変数を作ることもできます:String
は、Character
の配列をイニシャライザの引数として渡して構築することができます:String
同士は、加算演算子(+
)使用して新しい String
を生成できます:+=
)を使用して、既存の String
変数に String
を追加することもできます:String
の append()
メソッドを使用して Character
を追加することもできます。NOTE 既存のCharacter
にString
やCharacter
を追加することはできません。Character
には、 1 つの文字だけしか含められません。
badStart
と end
を連結すると、2 行の文字列を生成していますが、これは期待した結果ではありません。badStart
の最後の行に改行が入っていないため、end
の最初の行と混ざってしまいます。一方で、goodStart
の最初と最後の行は改行で終わっているので、end
と連結した結果は 3 行になり、期待通りになります。String
を構築する方法です。文字列補間は 1 行でも複数行でも使用することができます。文字列に入れるそれぞれの値は、両括弧で囲み、その前にバックスラッシュ(\
)をつけます。multiplier
は \(multiplier)
として文字列に挿入します。このプレースホルダは、実際に文字列を生成するタイミングで評価され、multiplier
の実際の値に置き換えられます。multiplier
は文字列の後半の大きな式の中でも使われています。この式は、Double(multiplier) * 2.5
を計算して、その結果の(7.5
)を文字列に挿入します。この場合、\(Double(multiplier) * 2.5)
と書いて文字列リテラルに含まれます。NOTE 補間された文字列内の括弧の中に書かれた式には、エスケープしていないバックスラッシュ(\
)、キャリッジリターン、改行を含めることはできません。他の文字列リテラルは含めることができます。
String
や Character
は、このセクションでも記載していますが、完全に Unicode に準拠しています。String
型は Unicode スカラから構築されています。Unicode スカラは 21 ビットの文字と修飾子で構成されています。例えば、U+0061
は LATIN SMALL LETTER A ("a")
、U+1F425
は FRONT-FACING BABY CHICK ("🐥")
です。LATIN SMALL LETTER A
や FRONT-FACING BABY CHICK
のように一般的には名前が付いています。Character
の全てのインスタンスは 1 つの_拡張書記素クラスタ_を表しています。拡張書記素クラスタは、人間が読み取れる 1 文字を生成するための 1 つ以上の Unicode スカラの配列です(1 つ以上の Unicode スカラが必要な場合は合成されます)。é
は、1 つの é
(LATIN SMALL LETTER E WITH ACUTE
または U+00E9
)を表すことができます。一方で、同じ文字をスカラのペアで表すこともできます。e
(LATIN SMALL LETTER E
または U+0065
)の後ろに COMBINING ACUTE ACCENT
スカラ(U+0301
)を付けます。COMBINING ACUTE ACCENT
スカラはその前のスカラに視覚的に適用されて、Unicode を理解できるシステムがテキストをレンダリングする際に、e
を é
に変換します。é
は拡張書記素クラスタの 1 つの Character
型の値として表されます。最初のケースでは、1 つのスカラを含んでいるクラスタで、2 番目のケースは、2 つのスカラのクラスタとなります。Character
として表す柔軟な方法です。例えば、韓国語のハングル文字は、合成または展開されたスカラの配列で表すことができます。これらのどちらも、 Swift では 1 つの Character
と見なされます。COMBINING ENCLOSING CIRCLE
または U+20DD
)のスカラを 1 つの Character
の一部として、他の Unicode スカラを囲むことができます。Character
を作成するために、2 つのスカラを組み合わせます。例えば、REGIONAL INDICATOR SYMBOL LETTER U
(U+1F1FA
)と REGIONAL INDICATOR SYMBOL LETTER S
(U+1F1F8
):Character
の数を得るには、文字列の count
プロパティを使いましょう。Character
に拡張書記素クラスタを使用しているということは、文字列の連結や変更が必ずしも文字列内の文字数に影響を与えるわけではない、ということに注意してください。cafe
という単語は 4 つの文字から新しい文字列を初期化した場合、COMBINING ACUTE ACCENT (U+0301)
を最後に追加すると、最後の文字は e
から é
に変わりますが、文字のカウントは 4
のままです。NOTE 拡張書記素クラスタは複数の Unicode スカラを組み合わせることができます。つまり、異なった文字や、同じ文字でも、異なったスカラで表された文字はメモリ上に保持する際に異なったメモリサイズが必要になる場合があります。これは、Swift の文字は、それぞれの文字で同じメモリ量ではない、ということです。結果として、文字列内の文字を数えるには、拡張書記素クラスタの境界を判断しなければならず、文字列全体を繰り返し処理しないと計算することができません。特に長い文字列を扱っている場合は、count
プロパティを使用すると文字数をカウントするために文字列全体に繰り返し処理を行なっていることに気をつけてください。count
プロパティから返ってくる文字数は、同じ文字列であってもNSString
のlength
と異なる場合があります。NSString
のlength
は UTF-16 での文字数カウントで、Unicode の拡張書記素クラスタでの数ではありません。
String
は`String.Index`という紐づいたインデックスの型を持っており、それぞれは文字列の Character
の位置と対応関係があります。Character
の位置を特定するには、Unicode スカラを文字列の最初または最後から反復して探さなければなりません。こういった理由から Swift の String
のインデックスは数値にすることはできません。String
の最初の Character
の位置を知るためには、startIndex
プロパティを使いましょう。endIndex
プロパティは String
の最後の Character
の位置の次の位置です。つまり、endIndex
プロパティは文字列の subscript に使用してはいけません。String
が空ならば、startIndex
と endIndex
は等しくなります。index(before:)
と index(after:)
を使用して、あるインデックスの前後のインデックスにアクセスできます。あるインデックスから離れた位置のインデックスにアクセスするためには、上記 2 つのメソッドを繰り返し呼ぶのではなく、index(_:offsetBy:)
を使います。String
のある特定の位置の Character
へアクセスするには、subscript 構文を使います。Character
にアクセスしたり、実行時エラーが起きます。indices
プロパティを使いましょう。NOTECollection
プロトコルに準拠したどんな型にも、startIndex
、endIndex
プロパティ、index\(before:)
、index(after:)
、index(_:offsetBy:)
メソッドを使用することができます。これは、Array
、Dictionary
、Set
といったコレクションの型と同様に、今紹介しているString
にも含まれています。
insert(_:at:)
を使い、他の文字列を挿入したい場合は、insert(contentsOf:at:)
を使います。remove(at:)
を使い、部分文字列を削除したい場合は removeSubrange(_:)
を使います。NOTERangeReplaceableCollection
プロトコルに準拠したどんな型にも、insert(_:at:)
、insert(contentsOf:at:)
、remove(at:)
、removeSubrange(_:)
メソッドを使用することができます。これは、Array
、Dictionary
、Set
といったコレクションの型と同様に、今紹介しているString
も含んでいます。
prefix(_:)
などのメソッドを使用するなど)、Substringインスタンスが結果として取得できます。部分文字列には文字列とほぼ同じメソッドを使用することができます。つまり、部分文字列を文字列と同じような方法で扱うことができます。しかし、文字列とは異なり、部分文字列は、文字列に対して何かアクションを起こしているほんの短い間だけに使います。処理の結果をより長い期間保持するときは、部分文字列を String
のインスタンスに変換します。例えば:greeting
は文字列です。つまり、文字列を構築する文字を保持したメモリ領域を持っています。beginning
は greeting
の部分文字列です。greeting
が使用しているメモリを再利用しています。反対に、newString
は文字列で、部分文字列から生成されたときに独自のメモリ領域を持ちます。下記の図はこの関係を示しています。NOTE 文字列と部分文字列は、StringProtocolに準拠しています。つまり、文字列操作を行う関数は、StringProtocol
の値を受け取るとしばしば便利なことがあります。文字列、部分文字列のどちらを使用しても、その関数を使用することができます。
String
または Character
の完全一致、前方一致、後方一致です。LATIN SMALL LETTER E WITH ACUTE
(U+00E9
)は、LATIN SMALL LETTER E
(U+0065
)の最後に COMBINING ACUTE ACCENT
(U+0301
)を付け加えた文字列とルール上等しくなります。どちらの拡張書記素クラスタも é
という文字を表す妥当な方法なので、これらはルール上等しいと見なされます:LATIN CAPITAL LETTER A
(U+0041
または "A"
)はロシア語で使われている CYRILLIC CAPITAL LETTER A
(U+0410
または "А"
)と等しくありません。一見似ていますが、同じ言語的な意味を持っていません:NOTE Swift の文字列と文字の比較は、ロケール依存です。
hasPrefix(_:)
と hasSuffix(_:)
メソッドを使います。どちらも 1 つの String
型の引数を受け取り、Bool
値を返します。hasPrefix(_:)
を使用して romeoAndJuliet
配列から Act 1 のシーンの数を数えます。hasSuffix(_:)
を使用して Capulet マンションや修道士ローレンスの周りで起きたシーンの数を数えてみます。NOTEhasPrefix(_:)
とhasSuffix(_:)
メソッドは、文字ごとに各文字列の拡張書記素クラスタを使用してルール上等しいかどうかを調べます(String and Character Equality(文字と文字列の等価性)に記載)。
for-in
文で文字列を繰り返し処理する場合、Unicode 拡張書記素クラスタとして個々の Character
にアクセスできます。このプロセスはWorking with Characters(文字配列の取扱)で記載しています。String
にアクセスできます:utf8
プロパティを使用してアクセス)utf16
プロパティを使用してアクセス)unicodeScalars
プロパティを使用してアクセス)D
、 o
、 g
、 ‼
(DOUBLE EXCLAMATION MARK
または Unicode スカラ U+203C
)と 🐶 文字 (DOG FACE
, or Unicode スカラ U+1F436
):String
の utf8
プロパティを使います。このプロパティの型は、String.UTF8View
で、符号なし 8 ビット(UInt8
)のコレクションで、文字列の UTF-8 表現のそれぞれのバイトを表しています:codeUnit
(68
、111
、103
)は、ASCII 表現の D
、o
、g
を UTF-8 表現で表しています。 次の 3 つの 10 進数の codeUnit
(226
、128
、188
)は、DOUBLE EXCLAMATION MARK
を 3 バイトの UTF-8 表現で表しています。最後の 4 つの codeUnit
(240
、159
、144
、182
)は、DOG FACE
文字を 4 バイトの UTF-8 表現で表しています。String
の utf16
プロパティを使います。このプロパティの型は、String.UTF16View
で、符号なし 16 ビット(UInt16
)のコレクションで、文字列の UTF-16 表現のそれぞれのバイトを表しています:codeUnit
(68
、111
、103
)は、D
、o
、g
を UTF-16 表現で表しています。これは UTF-8 と同じです。(Unicode スカラは ASCII 文字を表しているため等しくなります)
4 番目の codeUnit
(8252
)は、16 進数の 203C
と等しく、DOUBLE EXCLAMATION MARK(U+203C)
を表しています。この文字は UTF-16 だと 1 つのコードユニットで表すことができます。codeUnit
(55357
, 56374
)は UTF-16 のサロゲートペアで、DOG FACE
文字を表しています。これは上位サロゲートの U+D83D
(10 進数だと 55357
)と下位サロゲートの U+DC36
(10 進数だと 56374
)です。String
の unicodeScalars
プロパティを使います。このプロパティの型は、UnicodeScalarView
で、UnicodeScalar
のコレクションです。UnicodeScalar
には UInt32
で表される 21 ビットのスカラを返す value
プロパティを持っています。UnicodeScalar
(68
、111
、103
)の value
プロパティは、D
、o
、g
を表しています。codeUnit
(8252
)は、16 進数の 203C
と等しく、DOUBLE EXCLAMATION MARK(U+203C)
を表しています。UnicodeScalar
(128054
)は、16 進数の 1F436
と等しく、DOG FACE
文字を表す Unicode スカラ U+1F436
と等しいです。value
プロパティを探索する代わりに、それぞれの UnicodeScalar
値から新しい String
を構築することもできます。例えば文字列補間で使えます: