Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve "String interpolation produces a debug description for an optional value; did you mean to make this explicit?" in Xcode 8.3 beta?

Since beta 8.3, zillions warnings "String interpolation produces a debug description for an optional value; did you mean to make this explicit?" appeared in my code.

For example, the warning popped in the following situation up, where options could lead to nil:

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

As previously designed, it was ok for me (and the compiler) the optionals to be interpolated as 'nil'. But compiler changed its mind.

What the compiler suggests is to add a String constructor with description as follows:

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

Obviously, the results is explicit but also very very cumbersome in my opinion. Is there a better option? Do I have to fix all those warning or better wait for the next beta?

Screenshot for description

like image 638
Stéphane de Luca Avatar asked Mar 01 '17 22:03

Stéphane de Luca


Video Answer


1 Answers

This is a change that was made in this pull request due to the fact that interpolating Optional(...) into the resultant string is often undesirable, and can be especially surprising in cases with implicitly unwrapped optionals. You can see the full discussion of this change on the mailing list here.

As mentioned in the pull request discussion (although unfortunately not by Xcode) – one slightly nicer way to silence the warning than the use of String(describing:) is to add a cast to the optional type of whatever you're interpolating, so for example:

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 

Which can also be generalised to 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 

In Swift 5, with the new string interpolation system introduced by SE-0228, another option is to add a custom appendInterpolation overload for 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 

And, if desired, you could even remove the argument label to disable the warning entirely within a module (or within a particular file if you mark it as 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 

Though personally I would prefer to keep the argument label.

like image 107
Hamish Avatar answered Oct 23 '22 07:10

Hamish