文字列内でOptional型を埋め込んだ時のアレをStringInterpolationをいじって回避したった
ざっくりまとめ。
StringInterpolation
と聞いてピンときますか?- StringInterpolation とは文字列補間という意味らしくて、文字列内で変数の値を展開してくれる例のアレです
"text: \(text)"
こういう感じのやつです
- この展開は便利だけれど
Optional
の場合ちょっと困りますtext: Optional("nullable")
上記の例で text が Optional だとこうなる
- Swift 5 から
StringInterpolation
をカスタマイズできるのでこの問題をサクッと回避できます!
です。
環境
- Xcode v10.2
- Swift v5
問題
let text: String? = "nullable"
let num: Int? = nil
print("text: \(text) - num: \(num)")
これで出力されるものがどうなるかわかりますか?
Swift を嗜んでおられる人ならわかりますね。
「あーあの問題でしょ(笑)」みたいな
text: Optional("nullable") - num: nil
正解はこう出力されます。
でも期待しているものはおそらくそうではないはず。
text: nullable - num:
こういうのを期待して書いたはずです。(多分
(まぁ今の Xcode だと warning を出してくれるのでやるまでもく修正しちゃうんですけどね(笑))
回避策
要は Optional だからそうなるので、Unwrap してあげてから出力させればいいということです。
やり方はいくつかあるのですけど、1行で書くとしたら...
print("text: \(text ?? "") - num: \(num ?? 0)")
こういう感じです。
(num が nil で 0 と出ちゃうのでちょっと違いますけど)
StringInterpolation をカスタマイズして回避する
ここからが本題です。
Swift 5 ではその StringInterpolation をカスタマイズ出来るようになりました。
既存の挙動を変えることも出来るし、全く別物も作れたりします。
それで、その機能をつかえば上記問題(?)も回避できるのでは!?という話です。
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: CustomStringConvertible?) {
guard let value = value else {
return
}
appendLiteral(String(describing: value))
}
}
let text: String? = "nullable"
let num: Int? = nil
print("text: \(text) - num: \(num)")
この出力は
text: nullable - num:
こうなります!💪
これで、Unwrap しなくても気軽に埋め込めるようにできますね!
これが良いのかどうかっていう議論は別でありますけど😇
参考
- Swift 5 で String Interpolation をカスタマイズする - Qiita
これをみてなにか遊べないかな〜と考えて思いついたのが今回の記事です(笑)