ベータ8.3以降、無数の警告「文字列補間によりオプション値のデバッグ記述が生成されます。これを明示的にするつもりですか?」私のコードに登場しました。
たとえば、次の状況では警告が表示され、オプションがnilになる可能性があります。
let msg = "*** Error \(options["taskDescription"]): cannot load \(sUrl) \(error)"
以前に設計されたように、私(およびコンパイラー)が「nil」として補間されるオプションは問題ありませんでした。しかし、コンパイラは考えを変えました。
コンパイラが提案するのは、次の説明を含むStringコンストラクターを追加することです。
let msg = "*** Error \(String(describing: options["taskDescription"])): cannot load \(sUrl) \(error)"
明らかに、結果は明白ですが、私の意見では非常に面倒です。より良いオプションはありますか?これらの警告をすべて修正する必要がありますか、それとも次のベータを待つ必要がありますか?
これは このプルリクエスト で行われた変更です。結果の文字列にOptional(...)
を挿入することは望ましくないことが多く、特に驚くべきことです 暗黙的にラップされていないオプションの場合 =。この変更の詳細については、メーリングリスト here で確認できます。
プルリクエストの説明で述べたように(残念ながらXcodeによるものではありませんが)、String(describing:)
を使用するよりも警告を黙らせるには、補間するオプションの型にキャストを追加するのが少し良い方法です。たとえば、
var i: Int? = 5
var d: Double? = nil
print("description of i: \(i as Int?)") // description of i: Optional(5)
print("description of d: \(d as Double?)") // description of d: nil
これはas Optional
に一般化することもできます:
print("description of i: \(i as Optional)") // description of i: Optional(5)
print("description of d: \(d as Optional)") // description of d: nil
Swift 5では、 SE-0228 によって導入された新しい文字列補間システムで、別のオプションは appendInterpolation
のカスタムDefaultStringInterpolation
オーバーロードを追加することです。
extension DefaultStringInterpolation {
mutating func appendInterpolation<T>(optional: T?) {
appendInterpolation(String(describing: optional))
}
}
var i: Int? = 5
var d: Double? = nil
print("description of i: \(optional: i)") // description of i: Optional(5)
print("description of d: \(optional: d)") // description of d: nil
また、必要に応じて、引数ラベルを削除して、モジュール内(またはfileprivate
としてマークした場合は特定のファイル内)で警告を完全に無効にすることもできます。
extension DefaultStringInterpolation {
mutating func appendInterpolation<T>(_ optional: T?) {
appendInterpolation(String(describing: optional))
}
}
var i: Int? = 5
var d: Double? = nil
print("description of i: \(i)") // description of i: Optional(5)
print("description of d: \(d)") // description of d: nil
個人的には、引数ラベルを保持することを好みます。
この問題に対処する2つの簡単な方法。
オプション1:
最初の方法は、 "force-unwrapping"bang (!)を使用して返す値です。
var someValue: Int? = 5
print(someValue!)
出力:
5
オプション2:
より良い方法である可能性のある他の方法は、 "safely-unwrap"返される値です。
var someValue: Int? = 5
if let newValue = someValue {
print(newValue)
}
出力:
5
オプション2を使用することをお勧めします。
ヒント:常にラップ解除する値があるかどうかわからないため、可能な場合は強制的にアンラップ(!)しないでください。
string(describing:optional)を使用するのが最も簡単なようです。
デフォルト値?? Intなどの非文字列には意味がありません。
[。 0。
テストするプレイグラウンドコード:
var optionalString : String? = nil
var optionalInt : Int? = nil
var description_ = ""
description_ = description_ + "optionalString: \(String(describing: optionalString))\r"
description_ = description_ + " optionalInt: \(String(describing: optionalInt))\r"
print(description_)
出力
optionalString: nil
optionalInt: nil
Xcode 8.3に更新し、多くの警告メッセージを取得した後、コードと出力の両方で「String(describing :)」を使用することの冗長性を軽減する、追加が簡単な元の出力動作に似た次のものを思いつきました。
基本的に、オプションの事柄を説明する文字列を提供するオプションの拡張子を追加するか、設定されていない場合は単に「nil」を追加します。さらに、オプションの文字列が文字列の場合は、引用符で囲みます。
extension Optional {
var orNil : String {
if self == nil {
return "nil"
}
if "\(Wrapped.self)" == "String" {
return "\"\(self!)\""
}
return "\(self!)"
}
}
そして遊び場での使用:
var s : String?
var i : Int?
var d : Double?
var mixed = "s = \(s.orNil) i = \(i.orNil) d = \(d.orNil)" // "s = nil i = nil d = nil"
d = 3
i = 5
s = ""
mixed = "s = \(s.orNil) i = \(i.orNil) d = \(d.orNil)" // "s = "" i = 5 d = 3.0"
s = "Test"
d = nil
mixed = "s = \(s.orNil) i = \(i.orNil) d = \(d.orNil)" // "s = "Test" i = 5 d = nil"
次のリンクからの助けをありがとう:
これについてはOle Begemanの修正を参照 。大好きです。次のように使用できる???
演算子を作成します。
var someValue: Int? = 5
print("The value is \(someValue ??? "unknown")")
// → "The value is 5"
someValue = nil
print("The value is \(someValue ??? "unknown")")
// → "The value is unknown"