如何解决“string插值为可选值生成debugging描述; 你的意思是明确的吗?“在Xcode 8.3 beta中?

自从beta 8.3以来,zillions警告“string插值为可选值产生一个debugging描述;你的意思是明确吗? 出现在我的代码中。

例如,在以下情况下popup警告,其中选项可能导致无效:

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

按照以前的devise,对于我(和编译器)来说,可选项被插入为'nil'。 但编译器改变了主意。

编译器build议的是添加一个string构造函数的描述如下:

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

显然,结果是明确的,但在我看来也非常麻烦。 有更好的select吗? 我是否必须修复所有这些警告或更好地等待下一个testing?

描述的屏幕截图

这是在这个拉取请求中所做的一个改变,这是因为将Optional(...)插入到结果string中往往是不可取的,而且对于隐式解包的可选项,情况尤其令人惊讶。 您可以在这里查看邮件列表上有关此更改的完整讨论。

正如拉请求讨论中提到的(虽然不幸的是不是由Xcode) – 一个稍微好一点的方式来沉默的警告比使用String(describing:)是添加一个强制types的任意插入,所以为例:

 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 

另一个可能的方法来debugDescription警告是访问OptionaldebugDescription

 print("description of i: \(i.debugDescription)") // description of i: Optional(5) print("description of d: \(d.debugDescription)") // description of d: nil 

虽然值得注意的是CustomDebugStringConvertible的文档不鼓励直接访问debugDescription

似乎使用String(描述:可选)是最简单的。

默认值 ?? 对于非Strings(例如Int)是没有意义的。
如果Int为零,那么你希望日志显示'零'不默认到另一个Int例如0。

一些操场代码来testing:

 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并获取了很多警告消息后,我想出了更像原始输出行为的以下内容,易于添加,减less了在代码和输出中使用“String(描述:)”的冗长。

基本上,添加一个可选的扩展,给出一个string描述在可选的东西,或者只是“无”,如果没有设置。 另外,如果可选的东西是一个string,把它放在引号中。

 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" 

感谢您从以下链接获取帮助:

入住如果variables-是-一-可选,和什么types的-IT-包裹

两个更简单的方法来处理这个问题。

选项1:

第一个是通过爆炸你想要返回的价值,使用爆炸(!)

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

输出:

 5 

选项2:

另一种方式可能是更好的方法,就是“安全地解开”你想要返回的值。

 var someValue: Int? = 5 if let newValue = someValue { print(newValue) } 

输出:

 5 

会build议select2。

提示:尽可能避免强制展开(!),因为我们不确定是否始终具有解包的价值。

请参阅Ole Begeman对此的解决方法。 我喜欢它。 它创build了一个? 运算符,然后你可以这样使用:

 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" 

双击包含此警告的行中显示的黄色三angular形。 这将显示FixIt两种解决scheme。

屏幕截图添加

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

    使用它将变成String(describing:<Variable>)

    例如。 : String(describing: employeeName)

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

    使用它会变成(<Variable> ?? default value)

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