👽

【Swift UI】String(describing: )について 分かりやす過ぎる解説

2024/01/04に公開

String(describing: )

会社のソースコードで急に出てきた謎のString(describing: )について調べたことを書く!

ざっくりと説明すると何でも文字列で返すStringのInitializerです!

任意のインスタンスをString(describing: )に入れると文字列として表現してくれます。

公式ドキュメントに掲載されていた下記コードを元に使い方の一例を解説します。

struct Point {
    let x: Int, y: Int
}

let p = Point(x: 21, y: 30)
print(String(describing: p))
// Prints "Point(x: 21, y: 30)"

まず、コードではPointというstruct(構造体)型があり、let p = Point(x: 21, y: 30)でPointのインスタンスを作成しpに代入しています。
そして、String(describing: p)でString(describing: )にpを代入することで、"Point(x: 21, y: 30)"という文字列に変換されています。
最後にprint()でString(describing: p)作成した文字列を出力しています。

公式ドキュメント

https://developer.apple.com/documentation/swift/string/init(describing:)-67ncf

String(describing: )のルール

TextOutputStreamable
CustomStringConvertible
CustomDebugStringConvertible
出力の形を決めるために、3つのプロトコルが用意されています。

TextOutputStreamableプロトコルに準拠 write(to: )

TextOutputStreamableプロトコルが準拠されているインスタンスの場合は、.write(to: )を使うことで指定した形で結果が得られます。

画像小さくてごめん!

コード (クラス) コード 見た目

解説

PersonクラスにTextOutputStreamableを準拠させています。準拠させると

func write<Target>(to target: inout Target) where Target : TextOutputStream {}

を記述する必要があります。
write関数の中に出力させたい形を決めます。
上記コードでは、PersonクラスのインスタンスをString(describing: )に代入させた時に、「"こんな感じで出力されるぜ!(name)+(age)"」と出力させるようにしました。
出力の形は.writeの中に記述します。

CustomStringConvertibleプロトコルに準拠

CustomStringConvertibleプロトコルが準拠されているインスタンスの場合は、description変数で結果を取得できます。

コード (クラス) コード 見た目

解説

PersonクラスにCustomStringConvertibleプロトコルを準拠させたことで、var description: Stringが追加され、出力させたい形を決めます。
上記コードでは、var description: Stringをコンピューテッドプロパティにして、出力する形を「"CustomStringConvertibleに準拠させると(name)+(age)"」にしています。

CustomDebugStringConvertibleプロトコルに準拠

CustomDebugStringConvertibleプロトコルが準拠されているインスタンスの場合は、debugDescription変数で結果を取得できます。
CustomDebugStringConvertibleプロトコルは、あらゆる型にデフォルトで提供されているデバックテキスト表現をカスタムします!

コード (クラス) コード 見た目

解説

PersonクラスにCustomDebugStringConvertibleプロトコルを準拠させたことで、var debugDescription: Stringが追加され、出力させたい形を決めます。
上記コードでは、var debugDescription: Stringをコンピューテッドプロパティにして、出力する形を「"デバッグだよ。(name)+(age)"」にしています。

何も準拠しない

クラスをどのプロトコルにも準拠させない場合は、Swift標準ライブラリによって自動的に提供されます。

コード (クラス) コード 見た目

解説

Personをどのプロトコルにも準拠させない場合は、プロジェクト名(paintingAR)とクラス名(Person)が出力されました。

Personをstruck(構造体)型にすると結果が変わりました。

コード (クラス) コード 見た目

番外編 誰が最強か!!!

3つのプロトコルでどれが優先されるか見ます!
3つとも準拠させました。

最優先されたのは、CustomStringConvertibleでした。

次は、CustomStringConvertibleを消して残り二つで決めます。

TextOutputStreamable VS CustomDebugStringConvertible

優先されたのは、TextOutputStreamableでした。

結果

1 CustomStringConvertible (最優先)
2 TextOutputStreamable (優先)
3 CustomDebugStringConvertible

Discussion