[Swift] String の定義方法

     

TAGS:

⌛️ 2 min.
複数行にわたる String を定義する方法を改めて確認してみます。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Ventura 13.4 Beta
  • Xcode 14.3
  • iOS 16.4 beta

String 定義

Swift で 文字列を表す String を定義する方法を確認します。

たいていのプログラムでは、文字列を使用すると思われるので、Swift でプログラムを書く時にも非常に基本的なこととなります。

ですが、Swift では、さまざまな定義方法が用意されているので、(知らなかった)便利な定義方法を改めて理解したり、詳細を理解して使っていくのは 初級者からのステップアップに必要な気がします。

(前提)定義された文字列の確認方法

改行文字や空白文字を含めて 文字列の定義を考えると、その確認の仕方にも工夫が必要となります。

以降では、定義された文字列を 以下の SwiftUI のコードで表示して確認することとします。

struct ContentView: View {
    let str = "Hello, world!" // - ここの定義を変更して確認
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

上記の表示結果は以下のようになります。
赤い枠線を表示しているので、文字列の前後に空白文字等が含まれているかどうかも確認できます。

Helloworld

# 表示可能領域の影響では勝手に改行されることはないという前提です。(実際にもされていません)

” … ” を使った定義

上記の例では、1行の文字列を定義していました。お馴染みの Hello, world! です。

Swift で採用されている String の定義方法の1つは、前後を “(1つのダブル クォーテーション) を使って囲うことです。

他の言語でも同様の方法で定義することが多いので、Web 上での解説記事等でも (Swift に限らず) よくみます。

通常の文章中でも特定の文字列を説明する時に “Hello, world!” のように書きますので、プログラム言語に限らず、直感的に思われる定義方法と言えそうです。

let str = "Hello, world!" 

” を使った複数行定義

Swift の String 型は、複数行の文字列を保持することができます。

もう少し内部を考慮して言うと、String は 連続した複数の 文字 情報を持つことができ、その文字情報の1つとして改行文字を持つこともできるということです。

Swift では、改行文字は \n で表されます。

ということで、以下のようにすると、複数行の文字列を保持することができます。(スペースだった箇所を \n にしています)

let str = "Hello,\nworld!"

以下のような表示になります。

+n

# Swift 視点では 1行も複数行も関係なく、連続した文字データ と言える気がしますが、人間側からみると1行であるか2行であるかは 結構な違いです。

“”” … “”” を使った定義

” で囲う定義方法の他に、””” (3つのダブル クォーテーション) を使って、String を定義することもできます。

一番最初の “Hello, world!” を “”” を使って定義してみます。

struct ContentView: View {
    let str = """
Hello, world!
"""
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

コード上では、複数行に見えますが、””” を使って定義した時には 最初の “”” 直後の改行文字と 最後の “”” 直前の改行文字が無視されますので、(改行を持たない)1行の String が定義されています。

HelloWorld_3

“”” を使った複数行定義

“”” を使うと、複数行定義も以下のように定義できます。

struct ContentView: View {
    let str = """
Hello,
world!
"""
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

以下のような表示になります。

HelloWorld_2lines

” を使って複数行を定義するときは、\n を使って改行を明示的に書いていましたが、””” を使うと、通常のテキストと同様に改行することで、(データとしての)改行を定義できます。

個人の好みもあるかもしれませんが、””” を使った定義は、どちらかというと 複数行になるような 内部に改行コードを持つ String を定義する時に便利そうです。

“”” を使った 1行の定義

逆に、””” を使いつつ、複数行の文字列を 1つの String として定義することもできます。

struct ContentView: View {
    let str = """
Hello,\
world!
"""
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}
HelloWorld_1line

Hello, の次に来ている 改行の手前の \(バックスラッシュ) がポイントで、この \ でその次にある改行文字が無効にされ、1行の String になっています。

例えば、以下のようなケースで使用すると、コードの見やすさ向上に貢献してくれます。

非常に長い文字列を定義する時に そのままコードに記述すると 非常に長い行になってしまい、コードの見やすさが悪くなってしまいます。
そのような時に、上記の方法を使用すると長い文字列でも複数行に分けて記述することができるため、行の長さを適切な範囲に収めることができ、結果として コードの見やすさを向上させることができます。

    // 1行が非常に長い例
    let longlongStr1 = """
    Long long ago a little girl lived with her mother near the woods. One summer night ...
    """
    // 分割して定義している例
    let longlongStr2 = """
    Long long ago a little girl lived \
    with her mother near the woods. \
    One summer night ...
    """

“”” を使った時のインデントの扱い

“”” を使って定義したときに、コード中で 各行が左に寄ってしまうことが気になるかもしれません。

先ほどのコードでも プログラムのコードは、きれいにインデントされているのに、String 定義がそれを崩してしまっていました。

struct ContentView: View {
    let str = """
Hello,\            // ⬅️ 左によりすぎ
world!            // ⬅️ 左によりすぎ
"""
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

“”” を使って定義する時には、コード中のインデントとスペースを調整することができるようになっています。

具体的には、終端の “”” のインデント位置を調整することで、文字列の先頭のスペースを無視することができるようになります。

文字だけでの説明は難しいので、”The Swift Programming Language” から引用します。

multilineStringWhitespace@2x

終端の “”” より前にあるスペースは、その他の String 定義行からも削除し、それ以降のスペースは そのまま採用する ということです。

この機能を使用して先ほどのコードを書き直すと以下のようになります。(書き直しても動作は同じです)

struct ContentView: View {
    let str = """
            Hello,\
            world!
            """
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

先ほどのコードと比較して、str 定義がおさまるべき場所に収まっているため、読みやすくなっていることがわかります。

あくまで、終端の “”” の前にあるスペースが無視されるだけなので、以下のように定義すると、一定量のスペースが各行に追加されます。

struct ContentView: View {
    let str = """
        Hello,
        world!
    """
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

以下のような表示になるので、スペースが各行に追加されていることがわかります。

preSpace

なお、終端 “”” のいちよりも前に、str 定義の文字列が置かれているとエラーになります。
つまり、以下のような記述はエラーになると言うことです。


struct ContentView: View {
    let str = """
            Hello,\
world!                // 💣 ERROR!: Insufficient indentation of line in multi-line string literal
    """ 
    var body: some View {
        VStack {
            Text(str)
                .border(.red)
        }
    }
}

まとめ

Swift での String 定義 いろいろ

Swift での String 定義の方法を説明
  • “(ダブルクォーテーション) で囲う
  • 改行文字は \n を使う
  • “””(3つのダブルクォーテーション) で囲うと複数行のコードを使って定義できる
  • \ を使うと、String 定義行の改行を無効にできる
  • 終端の “”” の位置で String 定義行の先頭のスペース処理を調整できる

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です