2

So because I got bored of having to manually nil-coalesce optional values, I decided to make the common default values into nice and easy-to-use extensions on Optional, as seen below:

public extension Optional {
    var exists: Bool { return self != nil }
}

public extension Optional where Wrapped == String {
    var orEmpty: Wrapped { return self ?? "" }
}

public extension Optional where Wrapped == Int {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped == Double {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped == Float {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped == Bool {
    var orFalse: Wrapped { return self ?? false }
}

My issue arrives when attempting to use these on an optional value with a specific type.
I can call .orZero on a variable of type String? and get one of the following errors:

Ambiguous reference to member 'orZero'
'String?' is not convertible to 'Optional'

I'd like to know why Xcode is providing the .orZero properties of such an optional as valid auto-completion options? I would've thought the generic constraints would prevent me from being able to see them.
For what it's worth, I'm using Xcode 10.1, and Swift 4.2

Randika Vishman
  • 7,983
  • 3
  • 57
  • 80
royalmurder
  • 148
  • 1
  • 10

2 Answers2

1

.orZero being provided as an auto-completion is a bug. It can be circumvented by rewriting your extensions in terms of the appropriate literal protocols.

public extension Optional where Wrapped: ExpressibleByIntegerLiteral {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped: ExpressibleByBooleanLiteral {
    var orFalse: Wrapped { return self ?? false }
}

Expressed in this way, Swift can now figure out that .isZero ought not to be suggested for i.e. a variable of type String?, and if you try to call it anyway, it will give the error Type 'String' does not conform to protocol 'ExpressibleByIntegerLiteral'.

Marcel Tesch
  • 184
  • 3
  • 15
-1

Take a look at this.

In you extension .orZero is only for Int, Float, Double.

For String you have .orEmpty.

Deryck Lucian
  • 477
  • 6
  • 18
  • Thanks for the response, Deryck! I'm aware of the type limitations of the optional extensions above. My question is regarding why Xcode presents the wrong properties to me as autocompletion suggestions. I will update the question to outline this more obliquely. – royalmurder Nov 20 '18 at 11:41