I get no errors with the following function definition:
func calculate(price: String, prevBalance: Double) -> Double
{
guard let itemPrice = Double(price) else {
print("Error for the purchase amount")
return prevBalance
}
return prevBalance - itemPrice
}
But, if I change the type of the first parameter to Double:
func calculate(price: Double, prevBalance: Double) -> Double
{
guard let itemPrice = Double(price) else {
print("Error for the purchase amount")
return prevBalance
}
return prevBalance - itemPrice
}
I get the error:
Initializer for conditional binding must have Optional type, not ‘Double’
Why is that? If price
is a String type it can be converted by Double(price)
to a non-optional type, but if price
is a Double, it can only be converted to an Optional type? Alternatively, Double(price)
won’t return nil for a String type, but it can return nil for a Double type?
7
There’s 2 different initializers being called here:
Double.init?<S: StringProtocol>(_ text: S)
which takes anything conforming toStringProtocol
(such asString
itself) and is failable (i.e. returns an Optional) because the String might not represent a Double.Double.init(_ other: Double)
which just takes anotherDouble
, and can never fail, so it returns a non-optional.
1
Expanding on Alexander’s answer, guard let
is only valid if the expression on the right side of the equals sign is an Optional.
Double has multiple different initializers depending on the type of data you use to create the Double
. Creating a Double
from and Int or another Double
is not “failable”. It always works, so those initializers return a Double, not an Optional Double.
The initializer that takes a String (or other object that conforms to StringProtocol) can fail, and thus it returns an Optional.
guard let aDouble = Double("abc") else { return }
is valid because converting a String to a double can fail, and so returns an Optional.
The code
guard let aDouble = Double(1.23) else { return }
…is not valid, because Double.init(_: Double)
can’t fail, and doesn’t return an Optional. It always returns a Double.