LoginSignup
5
2

More than 5 years have passed since last update.

CustomStringConvertible を安全に String にするには

Posted at

CustomStringConvertible でミスっても型検査で気付けない問題の対処方法です。

本題

Swift は、ある型が文字列での表現形式を持っていることを表明する
CustomStringConvertible という protocol があります。

この protocol は、description という文字列のプロパティを持っていれば実装できます。そして、String(describing:) は与えられた引数が CustomStringConvertible ならば、この description を使うという仕様になっています。 例えば、次のように書けます:

struct Foo: CustomStringConvertible {
  let description: String
}


let foo = Foo(description: "😇")
let fooString = String(describing: foo) // OK

さて、ここで問題なのは String(describing:) がどんな型でも受け取れてしまうことです。そのため、CustomStringConvertible を実装し忘れても、型チェックでは気づけないのです:

extension String {
  init(describingSafely x: CustomStringConvertible) {
    self = x.description
  }
}


struct Ok: CustomStringConvertible {
  let description = "ok"
}

struct Ng {
}

print(String(describing: Ok())) // OK
print(String(describing: Ng())) // OK 😇アッ

そのため、下のような厳しめな対応をしておくと、CustomStringConvertible を忘れることがないでしょう:

extension String {
  init(describingSafely x: CustomStringConvertible) {
    self = x.description
  }
}


struct Ok: CustomStringConvertible {
  let description = "ok"
}

struct Ng {
}

print(String(describingSafely: Ok())) // OK
print(String(describingSafely: Ng())) // NG 😊

まとめ

厳しい

5
2
2

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
5
2