Swift 6.0 beta 日本語化計画 : Swift 6.0 beta
文字列と文字
string (文字列)は、"hello,world" や "albatross" などの、文字の一続きです。Swift の文字列は String 型として表現されます。String の内容は Character 値の集合 (collection) を含む、様々な方法でアクセスできます。
Swift の String と Character 型は、コード内のテキストを操作するために高速で Unicode 準拠の方法を提供します。文字列の作成と操作のための構文は、C 言語に似ている、文字列リテラル構文で、軽量で、読み取りやすいです。文字列の連結は、簡単で、+ 演算子で二つの文字列を結合し、文字列の可変性は、定数または変数を選択することによって管理され、Swift の他の値と同じです。文字列を使用して、定数、変数、リテラル、および式を、より長い文字列に挿入することもでき、文字列補間のプロセスとして知られています。これにより、表示、保存、および印刷用のカスタム文字列値を簡単に作成できます。
構文のこの単純さにもかかわらず、Swift の String 型は、高速で、現代的な文字列の実装を行なっています。すべての文字列は、コード化に依存しない Unicode 文字で構成されており、様々な Unicode の表現でこれらの文字にアクセスするためのサポートを提供しています。
注意: Swift の String 型は、Foundation の NSString クラスにブリッジされます。Foundation はまた、 NSString で定義されたメソッドを公開するため String を拡張します。これは、Foundation を import する場合は、キャストする事なく、String 上でこれらの NSString のメソッドにアクセスできる事を意味します。
Foundation と Cocoa で String を使用する方法の詳細については、String と NSString の間をブリッジする を参照してください。
文字列リテラル としてコード内で事前に定義された String 値を含めることができます。文字列リテラルは、二重引用符(")で囲まれた文字のシーケンスです。
定数または変数の初期値として文字列リテラルを使用して下さい。
文字列リテラル値で初期化されているので、Swift は someString 定数が String の型であると推測することに注意してください。
複数の行にまたがる文字列が必要な場合は、複数行の文字列リテラルを使用して下さい。文字のシークエンスは 3 つの二重引用符で囲みます。
複数行の文字列リテラルには、その前後の引用符の間にあるすべての行が含まれます。文字列は開始引用符 (""") の後の最初の行で始まり、終了引用符の前の行で終わります。つまり、開始前または改行で終了したいずれの文字列でもない事を意味します。
ソースコードが複数行の文字列リテラル内に改行を含む場合、その改行も文字列の値に表示されます。改行を使用してソースコードを読みやすくしたい場合、でも改行を文字列の値の一部にしたくない場合は、行末にバックスラッシュ(\)を記述して下さい。
改行で始まるか終わる複数行の文字列リテラルを作成するには、空白行を最初または最後の行として記述します。例えば:
複数行の文字列は、周囲のコードに合わせてインデントすることができます。閉じ引用符 (""") の前の空白は、Swift に他のすべての行の前に無視すべき空白を示します。しかし、終了引用符の前にあるものに加えて、行頭に空白を書くと、その空白 も 含められます。
上記の例では、複数行の文字列リテラル全体がインデントされていても、文字列の最初と最後の行は空白で始まりません。中間の行は終了引用符よりもインデントが多いので、余分な 4 つの空白のインデントで始まります。
文字列リテラルには、以下の特殊文字を含めることができます。
以下のコードは、これらの特殊文字の 4 つの例を示しています。wiseWords 定数には、2 つのエスケープした二重引用符が含まれています。dollarSign、blackHeart、および sparklingHeart 定数は、Unicode スカラー形式を示しています。
複数行の文字列リテラルは、1 つではなく 3 つの二重引用符を使用するため、複数行の文字列リテラルの中にはエスケープしないで、二重引用符 (") を含めることができます。複数行の文字列に """ を含めるには、引用符の少なくとも 1 つをエスケープします。たとえば、以下のようにします。
拡張した区切り文字 内に文字列リテラルを配置して、効果を呼び出さずに特殊文字を文字列に含めることができます。文字列を引用符 (") で囲み、シャープ記号 (#) で囲んで下さい。たとえば、文字列リテラル
#"Line 1\nLine 2"# を印刷すると、二つの行をまたぐ文字列ではなく改行エスケープシーケンス (\n) が印刷されます。
文字列リテラル内の文字の特殊効果が必要な場合は、エスケープ文字 (\) に続く文字列内のシャープ記号の数を一致させます。たとえば、文字列が #"Line 1\nLine 2"# で、改行したい場合は、代わりに
#"Line 1\#nLine 2"# を使用できます。同様に、###"Line1\###nLine2"### も改行します。
拡張した区切り文字を使用して作成された文字列リテラルは、複数行の文字列リテラルにすることもできます。拡張区切り文字を使用して、複数行の文字列にテキスト """ を含めることができ、リテラルを終了するデフォルトの動作をオーバーライドできます。次に例を示します。
長い文字列をビルドするための出発点として空の String 値を作成するには、変数に空の文字列リテラルを代入するか、イニシャライザの構文を使用して新しい String インスタンスを初期化するかのいずれかをします:
そのブール型の isEmpty プロパティをチェックして、String 値が、空であるかどうかを調べます。
特定の String が変更可能で(又は 変異可能 で) 変数に代入可能か(この場合変更可能)、定数に割り当てられるか(この場合変更不可能)を示します。
Swift の String 型は 値型 です。新しい String 値を作成する場合、それが関数やメソッドに渡された時、またはそれが定数または変数に代入された時、その String 値は コピー されます。それぞれの場合、既存の String 値の新しいコピーが作成され、元のバージョンではなく、新しいコピーが渡されるか代入されます。値型についての詳細は、構造体と列挙型は値型 に記載されています。
Swift のデフォルトでコピーされる String の動作は、関数やメソッドが、String 値を渡すとき、それがどこから来たのかは関係なく、その正確な String 値を所有することが明らかです。それをあなた自身が変更しない限り、渡された文字列は変更されないことを確信できます。
舞台裏では、絶対に必要な時だけ実際のコピーが起きるように、Swift のコンパイラは、文字列の使用を最適化します。これは値型として文字列を扱うときは、常に素晴らしいパフォーマンスを得られることを意味します。
文字列を for-in ループで反復処理することによって String の、個々の character の値にアクセスすることができます:
fot-in ループは、For-In ループ の中で説明されています。
代わりに、Character 型注釈を提供することによって、1文字の文字列リテラルから、スタンドアロンの Character 定数または変数を作成できます。
String 値は、そのイニシャライザへの引数として Character 値の配列を渡すことによって構築できます。
String 値は新しい String 値を作成するのに、加算演算子(+)で一緒に追加(または 連結 )することができます:
また、加算代入演算子(+=)で既存の String 変数に String 値を追加できます:
String 型の append( ) メソッドで String 変数に Character 値を追加できます。
複数行の文字列リテラルを使用して長い文字列の行をビルドしている場合は、最後の行を含め、文字列のすべての行を改行で終わらせます。例えば:
上記のコードでは、badStart を end と連結すると 2 行の文字列が生成されますが、これは望んだ結果ではありません。badStart の最後の行は改行で終わらないので、その行は end の最初の行と結合してしまいます。対照的に、goodStart の両方の行は改行で終了しており、したがって end と組み合わせると、結果は望んだとおり、3 行になります。
文字列補間 は、定数、変数、リテラル、及び式の混合から、それらの値を含める事により、文字列リテラルの中に新しい String 値を構築する方法です。単一の行と複数の行の文字列リテラルの両方で文字列補間を使用できます。文字列リテラルに挿入する各項目は、バックスラッシュ (\) を前に付けた括弧のペアで囲みます。
上記の例では、multiplier の値は \(multiplier) のように文字列リテラル内に挿入されています。文字列補間が実際の文字列を作成するために評価される時、このプレースホルダは、multiplier の実際の値に置き換えられます。
multiplier の値も、文字列の後の大きい式の一部です。この式は、Double(multiplier) * 2.5 の値を計算し、文字列に結果(7.5)を挿入します。この場合、式は、文字列リテラルの内側に含まれており、\(Double(multiplier) * 2.5) と書かれます。
拡張した文字列区切り文字を使用して、他の場合文字列補間として処理される文字を含む文字列を作成できます。例えば:
拡張した区切り文字を使用する文字列内で文字列補間を使用するには、文字列の先頭と末尾の # 記号の数に、バックスラッシュ後の # 記号の数を一致させます。例えば:
ユニコード は異なる書記体系でのコード化、表現、およびテキスト処理のための国際規格です。それは標準化された形式での全ての言語からの、ほぼ全ての文字を表現する事を可能にし、テキストファイルや Web ページのような外部ソースでそれらの文字を読み書きすることができます。このセクションで説明するように Swift の String と Character 型は、Unicode に完全に準拠しています。
舞台裏では、Swift 固有の String 型は Unicode スカラー値 からビルドされます。Unicode スカラーは、LATIN SMALL LETTER A ("a") の U+0061 や、または FRONT-FACING BABY CHICK ("🐥") の U+1F425 のような文字や修飾のユニークな 21 ビットの数値です。
21 ビットの Unicode スカラー値の全てが文字に割り当てられているわけではないことに注意してくださいーいくつかのスカラーは、将来の割り当てのためか、UTF-16 コード化のために予約されています。上記の例では文字に割り当てられているスカラー値は、典型的には LATIN SMALL LETTER A や、FRONT-FACING BABY CHICK のように、名前も持っています。
Swift の Character 型のすべてのインスタンスは単一の 拡張書記クラスタ を表します。拡張書記クラスタは、(組み合わせた時) 単一の、人間が読める文字を生成する 1 つ以上の Unicode スカラーのシーケンスです。
ここで例です。文字 é は、単一の Unicode スカラー(LATIN SMALL LETTER E WITH ACUTE, または U+00E9) é として表わすことができます。ただし、同じ文字がまた COMBINING ACUTE ACCENT スカラー(U+0301)が続く標準の文字 e (LATIN SMALL LETTER E、または U+0065) のスカラーの ペア として表すこともできます。COMBINING ACUTE ACCENT スカラーは、Unicode 対応のテキストレンダリングシステムによってレンダリングされる時、e を変化させて é として、それに先行するスカラーにグラフィカルに適用されます。
どちらの場合も、文字 é は、拡張書記クラスタを表す単一の Swift の Character 値として表されます。最初の場合は、クラスタは単一のスカラを含んでおり、第二の場合は、2つのスカラーのクラスタです。
拡張書記クラスタは、単一の Character 値として多くの複雑なスクリプト文字を表現するための柔軟な方法です。たとえば、韓国語のアルファベットからのハングルの音節は、合成済みかまたは分解されたシーケンスとして表すことができます。これらの表現の両方とも Swift の単一の Character 値としての資格があります:
拡張書記クラスタは、単一の Character 値の一部として他の Unicode スカラーを囲むように(COMBINING ENCLOSING CIRCLE や U+20DD のように) マークを囲むスカラーを有効にします。
地域のインジケータ記号の Unicode スカラーは、REGIONAL INDICATOR SYMBOL LETTER U (U+1F1FA) と、REGIONAL INDICATOR SYMBOL LETTER S (U+1F1F8)の組み合わせのような単一の Character 値を作るためにペアで組み合わされます。
文字列内の Character 値のカウントを取得するには、文字列の count プロパティを使用して下さい。
Characer 値の拡張書記クラスタを Swift が使うのは、その文字列の連結を意味し、修正が常には文字列の文字数に影響を与えないことに注意してください。
例えば、4文字の単語の cafe で新しい文字列を初期化し、その後で、文字列の最後に COMBINING ACUTE ACCENT(U+0301) を追加すると、結果の文字列はまだ 4 文字の count を持ち、4番めの文字は é であり、e ではありません。:
そのメソッドとプロパティを介して、またはサブスクリプトの構文を使用して文字列にアクセスし、変更します。
各 String 値には、関連した インデックス型 である、String.Index があります。これは、文字列内の各 Character の位置に対応します。
前述したように、異なる文字は、保存するのに異なる量のメモリを必要とするため、どの Character が特定の位置にあるかを決定するためには、その String の最初または終りから各 Unicode スカラーを繰り返し処理しなければなりません。このような理由から、Swift の文字列は整数値によってインデックス付けすることはできません。
String の最初の Character の位置にアクセスするため startIndex プロパティを使用して下さい。endIndex のプロパティは、String の最後の文字の直後の位置です。その結果、endIndex プロパティは、文字列のサブスクリプトへの有効な引数ではありません。String が空の場合、startIndex と endIndex は等しくなります。
与えられたインデックスの前後にあるインデックスにアクセスするには、String の index(before:) および index(after:) メソッドを使用して下さい。与えられたインデックスから離れたインデックスにアクセスするには、これらのメソッドの 1 つを複数回呼び出すのではなく、index(_:offsetBy:) メソッドを使用できます。
サブスクリプト構文を使用して、特定の String インデックスの Character にアクセスできます。
文字列の範囲外のインデックスまたは文字列の範囲外のインデックスにある Character にアクセスしようとすると、実行時エラーが発生します。
文字列内の個々の文字の全てのインデックスにアクセスするために indices プロパティーを使用して下さい。
指定されたインデックス位置で、文字列に単一の文字を挿入するには、insert(_:at:) メソッドを使用し、指定されたインデックス位置に別の文字列の内容を挿入するには、insert(contentsOf:at:) を使用して下さい。
指定されたインデックスにある文字列から単一の文字を削除するには、remove(at:) メソッドを使用し、また指定された範囲にある部分文字列を削除するには、removeSubrange(_:) メソッドを使用して下さい。
たとえば、サブスクリプトや prefix(_:) のようなメソッドを使用して、文字列から部分文字列を取得すると、結果は別の文字列ではなく Substring のインスタンスになります。Swift の部分文字列には文字列とほとんど同じメソッドがあります。つまり、文字列の場合と同じ方法で部分文字列を処理できます。ただし、文字列とは異なり、文字列に対してアクションを実行している間は、短い時間だけ部分文字列を使用して下さい。長い時間結果を格納する準備ができたら、部分文字列を String のインスタンスに変換して下さい。例えば:
文字列と同様に、各部分文字列には、部分文字列を構成する文字が格納されるメモリ領域があります。文字列と部分文字列の違いは、パフォーマンスの最適化として、元の文字列を格納するのに使用されるメモリの一部または別の部分文字列を格納するのに使用されるメモリの一部を部分文字列が再利用できることです。(文字列にも同様の最適化がありますが、2 つの文字列がメモリを共有する場合はそれらは同じです。) このパフォーマンスの最適化は、文字列または部分文字列を変更するまでメモリをコピーするパフォーマンスのコストを支払う必要がないことを意味します。前述のように、部分文字列は長期記憶には適していません。というのも元の文字列の記憶域を再利用するため、その部分文字列が少しでも使用されている限り元の文字列全体をメモリに保持しなければないからです。
上記の例で言えば、greeting は文字列です。つまり、文字列を構成する文字が格納されているメモリ領域がある事を意味します。beginning は greeting の部分文字列であるため、greeting が使用するメモリを再利用します。これとは対照的に、newString は文字列です。部分文字列から作成されたときは、独自の記憶域を持ちます。下の図は、これらの関係を示しています。
Swift は、テキストの値を比較する3つの方法を提供します:文字列と文字の等価性、接頭辞の等価性、接尾辞の等価性。
比較演算子 で説明したように、文字列と文字の等価性は、"等価"演算子(==)と"不等価"演算子(!=)でチェックできます。
それらの拡張書記クラスタが 正式に等価 である場合、2つの String 値(または2つの Character 値)は等しいと見なされます。それらが舞台裏で、異なる Unicode スカラーから構成されている場合でも、同じ言語的意味と外観を持っている場合、拡張書記クラスタは正式に等価です。
例えば、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, または "А")の文字と等価では ありません。文字は、見た目には似ていますが、同じ言語的な意味は持っていません:
文字列が特定の文字列の接頭辞や接尾辞を持っているかどうかをチェックするには、両方とも String 型の単一の引数を取りブール値を返す、文字列の hasPrefix(_:) と hasSuffix(_:) メソッドを呼び出します。
以下の例では、シェイクスピアの ロミオとジュリエット の最初の二つの幕から、シーンの場所を表す文字列の配列を考えてみます。
劇の第 1 幕ではシーンの数をカウントするのに romeoAndJuliet 配列と hasPrefix(_:) メソッドを使用できます。
同様に、キャピュレット公邸と、修道士ロレンス庵の周囲で行われるシーンの数をカウントするのに hasSuffix(_:) メソッドを使用できます。
Unicode 文字列が、テキストファイルまたはその他の記憶装置に書き込まれると、その文字列内の Unicode スカラーは、いくつかの Unicode に定義された コード化形式 のいずれか一つでコード化されます。各形式は コード単位 として知られる小さな塊に文字列をコード化します。これらは、UTF-8 コード化形式 (これは 8 ビットコード単位として文字列をコード化します) と、UTF-16 コード化形式 (これは 16 ビットコード単位として文字列をコード化します)、および UTF-32 コード化形式 (これは 32 ビットコード単位として文字列をコード化します) を含みます。
Swift は、文字列の Unicode 表現にアクセスするのに、いくつかの異なる方法を提供します。for-in 文で文字列を反復処理して、Unicode 拡張書記クラスタとしての個々の Character 値にアクセスできます。このプロセスは、文字を使った作業 で説明しました。
その他、3つの他の Unicode 準拠の表現のうちの一つの String 値にアクセスできます。
以下の各例で、D,o.g,‼ (DOUBLE EXCLAMATION MARK、または Unicode スカラー U+203C) の文字で構成されている以下の文字列の違った表現、および 🐶 文字(DOG FACE, または Unicode スカラー U+1F436)を示します:
その utf8 プロパティを反復処理することによって String の UTF-8 表現にアクセスできます。このプロパティは、String.UTF8View 型で、文字列の UTF-8 表現の各バイトの 1 つ 1 つは符号なし 8 ビット(UInt8)値であるコレクションです。
上記の例では、最初の3つの十進の codeUnit 値 (68、111、103) は UTF-8 表現がそれらの ASCII 表現と同じ文字 D、o、および g を表します。次の3つの十進の codeUnit 値(226、128、188) は DOUBLE EXCLAMATION MARK 文字の3バイトの UTF-8 表現です。最後の4つの codeUnit 値 (240、159、144、182) は、DOG FACE 文字の4バイトの UTF-8 表現です。
その utf16 プロパティを反復処理することによって String の UTF-16 表現にアクセスできます。このプロパティは、String.UTF16View 型で、文字列の UTF-16 表現の各 16 ビットコード単位の 1 つ 1つが符号なしの 16 ビット(UInt16) 値のコレクションです。
もう一度言うと、最初の3つの codeUnit 値(68、111、103)は、その文字の UTF-16 コード単位が、文字列の UTF-8 表現と同じ値を持つ D、o、および g を表します(これらの Unicode スカラーは ASCII 文字を表すため)。
4番目の codeUnit 値(8252)は DOUBLE EXCLAMATION MARK 文字の Unicode スカラー U+203C を表す 16 進値 203C と等しい十進数です。この文字は、UTF-16 の単一のコード単位として表すことができます。
5番目と6番目の codeUnit 値(55357 と 56374)は DOG FACE 文字の UTF-16 の代理ペア表現です。これらの値は、U+D83D (十進値 55357) の上位代理値と、U+DC36 (十進値 56374) の下位代理値です。
その unicodeScalars プロパティを反復処理することによって String 値の Unicode スカラー表現にアクセスできます。このプロパティは UnicodeScalar 型の値の集合である UnicodeScalarView 型です。
各 UnicodeScalar には UInt32 の値内で表現されるスカラーの 21 ビット値を返す value プロパティがあります:
最初の3つの UnicodeScalar 値(68、111、103)の value プロパティは再び文字 D、o、および g を表します。
4番目の codeUnit 値(8252)は再び 16 進値 203Cと等価な十進数であり、DOUBLE EXCLAMATION MARK 文字の Unicode スカラー U+203C を表します。
5番目で最後の UnicodeScalar,128054 の value プロパティは、16 進値 1F436 と等価な十進数であり、DOG FACE 文字の Unicode スカラー U+1F436 を表します。
これらの value プロパティを照会する代わりに、各 UnicodeScalar 値はまた、文字列の補間のように、新しい String 値の構成のためとしても使用できます。