杏z学習帳

Swift、Unityなどを中心に節操なく手を出してますまる

文字列内でOptional型を埋め込んだ時のアレをStringInterpolationをいじって回避したった(2019/04/10)

[Swift]文字列内でOptional型を埋め込んだ時のアレをStringInterpolationをいじって回避したった

ざっくりまとめ。

です。

環境

問題

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 しなくても気軽に埋め込めるようにできますね!

これが良いのかどうかっていう議論は別でありますけど😇

参考