22
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUI.TextにIntが変数展開されたStringを渡すと3桁区切りになる

Last updated at Posted at 2021-06-28

スクリーンショット 2021-06-28 20.58.45.png

いったいどうなってるんだってばよ!!

print(String(1234))
// -> 1234
print("\(1234)")
// -> 1234

もちろん、普通に変数展開されたStringをprintしても3桁区切りにはなりません。

スクリーンショット 2021-06-28 21.01.25.png

どうやら、変数展開している箇所にこの不思議な挙動の秘密がありそうです。

この挙動は一体なんなのか

調べてみたところ、こちらの記事に出会いました。すごくよくまとまっていて、Int以外の変数展開についても書かれているのでぜひこちらも見てみてください。(Textの変数展開にImageや別のText入れられるの知らなかった...)

要約すると

  • SwiftUI.Textはイニシャライザの引数として LocalizedStringKey を受け取る
  • LocalizedStringKeyExpressibleByStringInterpolation に準拠する型で、 StringInterpolationProtocol に準拠した型 StringInterpolation を内部的に持っている
  • SwiftUI は LocalizedStringKey.StringInterpolation を拡張した appendInterpolation を定義することで、カスタマイズされた変数展開が利用できるようになっている

このような実装によって、カスタマイズされた変数展開ができるようになっています。

その上で今回の挙動について紹介

SwiftUIに定義されている appendInterpolation には public mutating func appendInterpolation<T>(_ value: T) where T : _FormatSpecifiable というメソッドがあり、今回の挙動はこれが関係しています。

public protocol _FormatSpecifiable : Swift.Equatable {
    associatedtype _Arg : Swift.CVarArg
    var _arg: Self._Arg { get }
    var _specifier: Swift.String { get }
}

_FormatSpecifiable の定義は上のようになっていて

extension Int : SwiftUI._FormatSpecifiable
extension Int8 : SwiftUI._FormatSpecifiable
extension Int16 : SwiftUI._FormatSpecifiable
extension Int32 : SwiftUI._FormatSpecifiable
extension Int64 : SwiftUI._FormatSpecifiable
extension UInt : SwiftUI._FormatSpecifiable
extension UInt8 : SwiftUI._FormatSpecifiable
extension UInt16 : SwiftUI._FormatSpecifiable
extension UInt32 : SwiftUI._FormatSpecifiable
extension UInt64 : SwiftUI._FormatSpecifiable
extension Float : SwiftUI._FormatSpecifiable
extension Double : SwiftUI._FormatSpecifiable
extension CGFloat : SwiftUI._FormatSpecifiable

IntDouble などの数値型が _FormatSpecifiable に準拠していることがわかります。

ちなみに、Doubleを渡すと

スクリーンショット 2021-06-28 21.59.42.png

%.6f 相当のフォーマットがされていて、フォーマットのされ方も数値型によって違っているようです。

この _FormatSpecifiable を拡張した実装の中身までは確認できなかったのですが、 appendInterpolation には他にも public mutating func appendInterpolation<T>(_ value: T, specifier: String) where T : _FormatSpecifiable メソッドが生えてきて、

スクリーンショット 2021-06-28 21.57.09.png

のような使い方ができるため、各種の数値型に対して上のような文字列フォーマット指定子が _specifier でそれぞれ設定されているのだと思われます。

参考資料

22
8
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?