swift - 如何解決“字符串插值產生可選值的調試描述; 你是不是要明確這個?“在Xcode 8.3 beta中?




swift3 optional (4)

似乎使用String(描述:可選)是最簡單的。

默認值 ?? 沒有意義的非字符串,例如Int。
如果Int為nil,那麼您希望日誌顯示'nil'而不是默認為另一個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

從beta 8.3開始,zillions警告“字符串插值會為可選值生成調試描述;你的意思是明確說明嗎?” 出現在我的代碼中。

例如,警告在以下情況下彈出,其中選項可能導致nil:

let msg = "*** Error \(options["taskDescription"]): cannot load \(sUrl) \(error)"

如前所述,我(和編譯器)可以將選項插值為'nil'。 但是編譯器改變了主意。

編譯器建議添加一個帶有描述的String構造函數,如下所示:

let msg = "*** Error \(String(describing: options["taskDescription"])): cannot load \(sUrl) \(error)"

顯然,結果是明確的,但在我看來也非常麻煩。 有更好的選擇嗎? 我是否必須修復所有警告或更好等待下一個測試版?


兩種更簡單的方法來處理這個問題。

選項1:

第一個是通過 “強制 - 展開” 你希望使用爆炸 (!) 返回的值

var someValue: Int? = 5
print(someValue!)

輸出:

5

選項2:

另一種方式,可能是更好的方式 - 是 “安全 - 解包” 你想要返回的值。

var someValue: Int? = 5

if let newValue = someValue {
    print(newValue)
}

輸出:

5

建議選擇2。

提示:盡可能避免強行展開(!),因為我們不確定是否總是將值打開。


這是在 此拉取請求中 所做的更改,因為將 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 引入的新字符串插值系統,另一個選項是為 DefaultStringInterpolation 添加自定義 appendInterpolation 重載:

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

雖然我個人更喜歡保留參數標籤。


雙擊包含此警告的行上顯示的黃色三角形。 這將向 FixIt 展示兩種解決方案。

  1. 使用 String(describing:) 來消除此警告:

    使用它將成為 String(describing:<Variable>)

    例如。 : String(describing: employeeName)

  2. 提供 default value 以避免此警告:

    使用它將成為 (<Variable> ?? default value)

    例如: employeeName ?? “Anonymous” as! String employeeName ?? “Anonymous” as! String





string-interpolation