<div dir="ltr">I sent this to swift-users a few days ago but no one bit. I figure maybe someone here might have some insight into the internals for why this is happening. :)<div><div class="gmail_quote"><br><div dir="ltr">A coworker had the idea to get rid of the "Optional("Bob")" default string value for Optional<String> by adding the following extension to Optional:<div><br></div><div><div>extension Optional: CustomStringConvertible {</div><div> public var description: String {</div><div> switch self {</div><div> case .Some(let wrapped): return "\(wrapped)"</div><div> case .None: return "nil"</div><div> }</div><div> }</div><div>}</div></div><div><br></div><div>But this shows the following behavior:</div><div><br></div><div>name.description</div><div>=> "Bob"</div><div><br></div><div>String.init(name)</div><div>=> "Optional(\"Bob\")"</div><div><br></div><div>String(name) == name.description</div><div>=> false</div><div><br></div><div>Ok. So I dug around the source and found that String.init<T> delegates to _print_unlocked [0], where Optional is special cased at the top:</div><div><br></div><div><div>// Optional has no representation suitable for display; therefore,</div><div>// values of optional type should be printed as a debug</div><div>// string. Check for Optional first, before checking protocol</div><div>// conformance below, because an Optional value is convertible to a</div><div>// protocol if its wrapped type conforms to that protocol.</div><div>if _isOptional(value.dynamicType) {</div><div> let debugPrintable = value as! CustomDebugStringConvertible</div><div> debugPrintable.debugDescription.write(to: &target)</div><div> return</div><div>}</div></div><div><br></div><div>This seems non-ideal to me, but I understand that "because an Optional value is convertible to a protocol if its wrapped type conforms to that protocol" there's no easy way to tell if the Optional type itself conforms to CustomStringConvertible.</div><div><br></div><div>The print function is documented as using String.init<T> and in the source it appears to also be delegating to _print_unlocked. However, when I use it, I see the extension provided description!</div><div><br></div><div>print(name)</div><div>// => "Bob"</div><div><br></div><div>I've also confirmed it's actually the extension and not any other issue by returning hardcoded values from the description method.</div><div><br></div><div>So: what gives? :)</div><div><br></div><div>Why does the print function respect a CustomStringConvertible extension on Optional?</div><div><br></div><div>Thanks!</div><div>Ian</div><div><br></div><div><br></div><div><br></div><div>[0]: <a href="https://github.com/apple/swift/blob/master/stdlib/public/core/OutputStream.swift#L177" target="_blank">https://github.com/apple/swift/blob/master/stdlib/public/core/OutputStream.swift#L177</a></div></div>
</div><br></div></div>