Swift

Swiftのフォーマット文字列の仕様の調べ方

Swiftで、例えば数値から0埋めされた文字列にフォーマットする場合、`String`クラスのinit(format:_:)コンストラクタを活用して次のように記述します。

import Foundation

print(String(format: "%02d", 0)) // "00"

なぜFoundationフレームワークをインポートする必要があるのか?フォーマット文字列の仕様は?などの根拠がわからないままコピペして使うのは気持ち悪いですよね?

ということで納得できるまで調べ、フォーマット文字列の仕様とその情報へのたどり着き方、SwiftとObjective-Cとのつながりについてまとめました。

SwiftのStringクラスのinit(format:_:)の説明ではフォーマット文字列は不明

SwiftフレームワークのStringクラスのinit(format:_:)の説明には、次の記述しかありません。

Returns a String object initialized by using a given format string as a template into which the remaining argument values are substituted.

(テンプレートとしてのフォーマット文字列に続いて入力された値で置換して初期化されたStringオブジェクトを返す。)

この説明ではフォーマット文字列に何を指定すればいいのか、分かりませんね。

FoundationのNSStringクラスにフォーマット文字列の仕様へのリンクがある

FoundationフレームワークのNSStringクラスのinit(format:arguments:)コンストラクタの説明から、String Format Specifiersへのリンクがあります。

String Format Specifiersのページからはさらに、"For more details, see the IEEE printf specification"という記述があります。

IEEE printf specificationの記述を確認すると、

  • %が最初
  • 続いてフラグ
  • 0フラグを指定すると0埋めする
  • フラグに続いて幅を指定(0フラグを指定していればその幅で0埋め)

のような記載があるので、フォーマット文字列の裏付けになります。

String(format: "%02d", 0)

という記述にも、納得ができるようになりました。

SwiftのStringクラスはFoundationのNSStringクラスの機能を流用している

フォーマット文字列の仕様がどこにあるかは分かりました。

SwiftフレームワークのStringクラスを使っているはずなのに、なぜFoundationフレームワークのNSStringクラスのドキュメントを参照しなきゃいけないんだ?」

こんな疑問が浮かんでくると思います。

実はSwiftフレームワークのStringクラスは、部分的にFoundationフレームワークのNSStringクラスの機能を流用しています。

そのためFoundationフレームワークのインポートなしには、フォーマット機能が使えなかったりします。

import Foundation // この行が無いとビルドエラー

print(String(format: "%02d", 0)) // "00"

また、SwiftUIフレームワークを活用した開発の場合などは、import SwiftUIとすると自動的にFoundationフレームワークもインポートされるため、明示的にimport Foundationとする必要はありません。

import SwiftUI // SwiftUIをインポートするとFoundationもインポートされる

print(String(format: "%02d", 0)) // "00"

ちなみにSwiftUIフレームワーク以外にも、Foundationフレームワークの機能を内部で使っているライブラリをインポートすると、芋づる式にFoundationフレームワークまでインポートされます。

なぜSwiftのStringクラスはFoundationのNSStringクラスの機能を流用しているのか?

Swiftプログラミング言語がリリースされたのは、2014年で、それ以前はObjective-Cを使ってアプリ開発されていました。Swiftで必要になる機能の多くが、Objective-Cのライブラリとして既に存在していたため、それらをFoundationフレームワークとし、Swiftから流用できるよう設計されました。

FoundationフレームワークのNSStringを明示的に使用しなくても、SwiftフレームワークのStringを使用すると裏ではNSStringの機能を使える親切設計にされましたが、この親切心が逆にあだとなり、SwiftフレームワークのString(format:_:)コンストラクタの説明で、フォーマット文字列の仕様までしっかり記述されていないなど、Swift開発者にとってストレスフルな状況になってしまったのでした。

String(format:_:)コンストラクタはFoundationフレームワークをインポートしないと使えませんが、Foundationフレームワークをインポートしなくても使える機能もあります。また、Foundationフレームワークをインポートする前と後で挙動が変化する機能もあったりと、この辺りは若干カオスな仕様になっている点には注意が必要です。

"a".contains("") // 結果はtrue
import Foundation

"a".contains("") // Foundationをインポートすると結果はfalse

-Swift

© 2024 ヂまるBlog