文書   >   Swift   >   String


構造体


String


文字のコレクションである Unicode 文字列値。





宣言


struct String


概観


文字列は、"Swift" のような一連の文字であり、コレクションを形成します。Swift の文字列は、Unicode であり正確で、ロケールを区別せず、効率的になるように設計されています。String 型は Objective-C クラスの NSString とブリッジし、文字列で動作する C 関数との相互運用性を提供します。


文字列リテラルまたは文字列補間を使用して新しい文字列を作成できます。文字列リテラル は、引用符で囲まれた一連の文字です。


let greeting = "Welcome!"


文字列補間 は、含まれる式を評価し、結果を文字列形式に変換する文字列リテラルです。文字列補間は、複数の部分から文字列を作成する簡単な方法です。各式をカッコ内の文字列補間に包み込み、先頭にバックスラッシュを付けます。


let name = "Rosa"
let personalizedGreeting = "Welcome, \(name)!"
// personalizedGreeting == "Welcome, Rosa!"

let price = 2
let number = 3
let cookiePrice = "\(number) cookies: $\(price * number)."
// cookiePrice == "3 cookies: $6."


連結演算子(+) を使用して、文字列を結合します。


let longerGreeting = greeting + " We're glad you're here!"
// Prints "Welcome! We're glad you're here!"


複数行の文字列リテラルは、それぞれの行の区切り文字が3つの二重引用符 (""") で囲まれています。複数行の文字列リテラルの各行からインデントが削除され、最後の区切り文字のインデントと一致します。


let banner = """
          __,
         (           o  /) _/_
          `.  , , , ,  //  /
        (___)(_(_/_(_ //_ (__
                     /)
                    (/
        """


文字列の変更と比較


文字列には常に値の意味があります。文字列のコピーを変更してもオリジナルには影響を与えません。


var otherGreeting = greeting
otherGreeting += " Have a nice time!"
//otherGreeting == "Welcome! Have a nice time!"

print(greeting)
// Prints "Welcome!"


等号演算子(==) または関係演算子(<>= のような) を使用して文字列の等しさを比較することは、常に Unicode 正規表現を使用して実行されます。これは、文字列の異なる表現が等しいとすることを意味します。


let cafe1 = "Cafe\u{301}"
let cafe2 = "Café"
print(cafe1 == cafe2)
// Prints "true"


Unicode スカラー値 "\u{301}" は、前の文字にアクセントを含むように変更するので、"e\u{301}" は単一の Unicode スカラー値 "é" と同じ正規表現を持ちます。


基本的な文字列操作は、ロケール設定には影響を受けません。これにより、文字列の比較やその他の操作では、常に単一の安定した結果が得られ、Dictionary インスタンスのキーとして、およびその他の目的で文字列をキーとして使用できるようになります。


文字列要素へのアクセス


文字列は、人間が読める文字に近い、拡張書記素クラスタ のコレクションです。“é”、“김”、“🇮🇳” などの多くの個々の文字は、複数の Unicode スカラー値で構成できます。これらのスカラー値は、Unicode の境界アルゴリズムによって、Swift Character 型で表される拡張書記素クラスタに結合されます。文字列の各要素は、Character インスタンスによって表されます。


たとえば、長い文字列の最初の単語を検索するには、スペースを検索してから、その文字列の接頭辞からその位置までの部分文字列を作成します。


let name = "Marie Curie"
let firstSpace = name.firstIndex(of: " ") ?? name.endIndex
let firstName = name[..<firstSpace]
// firstName == "Marie"


firstName 定数は、Substring 型 (元の文字列の記憶域を共有しながら文字列の部分文字列を表す型) のインスタンスです。部分文字列は文字列と同じインタフェースを表します。


print("\(name)'s first name has \(firstName.count) letters.")
// Prints "Marie Curie's first name has 5 letters."


文字列の Unicode 表現にアクセス


異なる Unicode エンコーディングでコード化された文字列の内容にアクセスする必要がある場合は、文字列の unicodeScalars、utf16、または utf8 のいずれかのプロパティを使用します。各プロパティは、それぞれ異なる Unicode エンコーディングでコード化された一連のコード単位として文字列のビューへのアクセスを提供します。


すべての文字列で使用できるさまざまなビューを示すために、以下の例ではこの String インスタンスを使用しています。


let cafe = "Cafe\u{301} du 🌍"
print(cafe)
// Prints "Café du 🌍"


cafe 文字列は、文字列が表示されたときに見る事の出来るのは 9 文字のコレクションです。


print(cafe.count)
// Prints "9"
print(Array(cafe))
// Prints "["C", "a", "f", "é", " ", "d", "u", " ", "🌍"]"


Unicode スカラービュー


文字列の unicodeScalars プロパティは、Unicode のスカラー値のコレクションで、Unicode の基本単位である 21 ビットのコードです。各スカラー値は、Unicode.Scalar インスタンスで表され、UTF-32 コード単位と同等です。


print(cafe.unicodeScalars.count)
// Prints "10"
print(Array(cafe.unicodeScalars))
// Prints "["C", "a", "f", "e", "\u{0301}", " ", "d", "u", " ", "\u{0001F30D}"]"
print(cafe.unicodeScalars.map { $0.value })
// Prints "[67, 97, 102, 101, 769, 32, 100, 117, 32, 127757]"


unicodeScalars ビューの要素は、cafe 文字列内の各 Unicode スカラ値を構成します。特に、cafe"é" 文字の分解した形式を使用して宣言されているため、unicodeScalars には文字 "e"(101) とアクセント文字 "'"(769) の両方のスカラー値が含まれています。


UTF-16 ビュー


文字列の utf16 プロパティは、文字列の Unicode スカラ値の 16 ビットコード化形式である UTF-16 コード単位のコレクションです。各コード単位は UInt16 インスタンスとして格納されます。


print(cafe.utf16.count)
// Prints "11"
print(Array(cafe.utf16))
// Prints "[67, 97, 102, 101, 769, 32, 100, 117, 32, 55356, 57101]"


utf16 ビューの要素は、UTF-16 でコード化されたときの文字列のコード単位です。

これらの要素は、インデックス付き NSString API を通じてアクセスされるものと一致します。


let nscafe = cafe as NSString
print(nscafe.length)
// Prints "11"
print(nscafe.character(at: 3))
// Prints "101"


UTF-8 ビュー


文字列の utf8 プロパティは、文字列の Unicode スカラ値の 8 ビットコード化形式である UTF-8 コード単位のコレクションです。各コードユニットは UInt8 インスタンスとして格納されます。


print(cafe.utf8.count)
// Prints "14"
print(Array(cafe.utf8))
// Prints "[67, 97, 102, 101, 204, 129, 32, 100, 117, 32, 240, 159, 140, 141]"


utf8 ビューの要素は、UTF-8 でコード化されたときの文字列のコード単位です。この表現は、String インスタンスが C の APIに渡されるときに使用されるものと一致します。


let cLength = strlen(cafe)
print(cLength)
// Prints "14"


文字列の長さを数える


文字列の長さを知る必要があるときは、最初に長さを何に使うかを検討しなければなりません。スクリーンに表示される文字数を測定しているのか、特定のコード化で文字列に必要な記憶領域を測定しているのですか?単一の文字列は、異なるビューによって測定された場合、長さが大きく異なります。


例えば、大文字 A のような ASCII 文字は、その 4 つのビューのそれぞれで単一の要素として表されます。A の Unicode スカラー値は 65 で、UTF-16 と UTF-8 の両方で単一のコード単位に収まるのに十分小さいです。


let capitalA = "A"
print(capitalA.characters.count)
// Prints "1"
print(capitalA.unicodeScalars.count)
// Prints "1"
print(capitalA.utf16.count)
// Prints "1"
print(capitalA.utf8.count)
// Prints "1"


一方、絵文字の旗文字は、"\u{1F1F5}""\u{1F1F7}" のような Unicode スカラ値の組から構築されます。これらのスカラー値はそれぞれ大きすぎるため、単一の UTF-16 または UTF-8 コード単位には収まりません。その結果、文字列 "🇵🇷" の各ビューは異なる長さを報告します。


let flag = "🇵🇷"
print(flag.characters.count)
// Prints "1"
print(flag.unicodeScalars.count)
// Prints "2"
print(flag.utf16.count)
// Prints "4"
print(flag.utf8.count)
// Prints "8"


文字列が空かどうかを確認するには、ビューの 1 つの長さを 0 と比較する代わりに、その isEmpty プロパティを使用して下さい。isEmpty とは異なり、ビューの count プロパティを計算するには文字列の要素を繰り返す必要があります。


文字列ビュー要素へのアクセス


文字列の個々の要素を検索するには、タスクに適切なビューを使用します。たとえば、長い文字列の最初の単語を検索するには、文字列で空白を検索し、文字列の接頭辞からその点までの新しい文字列を作成します。


let firstSpace = name.firstIndex(of: " ") ?? name.endIndex
let firstName = name[..<firstSpace]
print(firstName)
// Prints "Marie"


文字列とそのビューはインデックスを共有するので、同じ firstSpace インデックスを使用して name 文字列の UTF-8 ビューにアクセスできます。


print(Array(name.utf8[..<firstSpaceUTF8]))
// Prints "[77, 97, 114, 105, 101]"


あるビューへのインデックスは、別のビュー内の正確に対応する位置を持っていないかもしれないことに注意してください。たとえば、上で宣言された flag 文字列は 1 文字で構成されていますが、UTF-8 としてコード化されている場合は 8 つのコード単位で構成されています。以下のコードは、flag.utf8 ビューの 1 番目と 2 番目の位置に定数を作成します。これらのインデックスで utf8 ビューにアクセスすると、1 番目と 2 番目のコードが UTF-8 ユニットを生成します。


let firstCodeUnit = flag.startIndex
let secondCodeUnit = flag.utf8.index(after: firstCodeUnit)
// flag.utf8[firstCodeUnit] == 240
// flag.utf8[secondCodeUnit] == 159


ただし、flag 文字列自体の要素にアクセスするために使用された場合、secondCodeUnit インデックスは特定の文字の位置に対応しません。特定の UTF-8 コード単位にのみアクセスするのではなく、そのインデックスはインデックスのコード化されたオフセットでの文字の位置として扱われます。secondCodeUnit の場合、その文字はまだ flag 自体です。


// flag[firstCodeUnit] == "🇵🇷"
// flag[secondCodeUnit] == "🇵🇷"


ある文字列のビューのインデックスが別のビューの正確な位置と一致することを検証する必要がある場合は、インデックスの samePosition(in:) メソッドまたは init(_:within:) イニシャライザを使用します。


if let exactIndex = secondCodeUnit.samePosition(in: flag) {
    print(flag[exactIndex])
} else {
    print("No exact match for this position.")
}
// Prints "No exact match for this position."


パフォーマンスの最適化


Swift の文字列には値の意味がありますが、文字列はデータをバッファに保存するためにコピーオンライト戦略を使用します。このバッファは、文字列の異なるコピーで共有することができます。文字列のデータは、複数の文字列インスタンスが同じバッファを使用している場合にのみ、変異する時、遅延してコピーされます。したがって、変異操作の順序の最初は、O(n) の時間と空間を要します。


文字列の連続した記憶領域がいっぱいになると、新しいバッファを割り当てければならず、データを新しい記憶領域に移動しなければなりません。文字列のバッファーは指数関数的に成長して、多くの追加操作で平均化したときに文字列に追加した時一定の時間がかかります。


String と NSString の間をブリッジする


全ての String インスタンスは、型キャスト演算子(as) を使用して NSString にブリッジでき、Objective-C で生成された全ての String インスタンスはその記憶領域として NSString インスタンスを使用できます。NSString の全ての任意のサブクラスは String インスタンスになりえるため、String インスタンスが NSString の記憶領域によって支えられている場合の表現や効率性は保証されません。NSString は不変であるため、記憶領域がコピーによって共有されているかのようになります。変異操作のシーケンスの最初のものは、要素が O(n) の時間と空間を要する一意の連続した記憶領域にコピーされ、ここで n は文字列のコード化された表現の長さです (基となる NSString に異常なパフォーマンス特性がある場合はそれ以上です)。


この議論で使用されている Unicode 用語の詳細については、Unicode.org の用語集 を参照してください。特に、この議論では、拡張書記素クラスタUnicode スカラ値、および 基本等価性 (canonical equivalence)について言及しています。


トピックス




String の作成


単一の文字列リテラルから文字列を作成することに加えて、空の文字列、既存の文字のグループを含む文字列、または別の文字列の内容を繰り返す文字列を作成することもできます。




文字列を調べる




Unicode データから文字列を作成する




フォーマットを使って文字列を作成




数値の変換




C 文字列の変換






@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
編集中
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@



入れ子になった型


目次
Xcode 10 の新機能

  • 言語:Swift
  • SDK
  • XCode 6.0.1
  • 宣言
  • 概観
  • トピックス












  • トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)