TehNewbie
TehNewbie

Reputation: 51

Value of optional type 'Float?' must be unwrapped to a value of type 'Float'

In short I am trying to do numerical operations between float values but cannot seem to find any solution.

var scale0: Float = 1.0
var scale1: Float = 1.0
var scale2: Float = 1.0
var scale3: Float = 1.0


let splitValues = message.characters.split{$0 == " "}.map(String.init)
    // These values are coming in realtime and constantly changing
    // Optional ?? incase we cannot convert string to float

    let value0 = Float(splitValues[0]) ?? Float("0.0")
    let value1 = Float(splitValues[1]) ?? Float("0.0")
    let value2 = Float(splitValues[2]) ?? Float("0.0")
    let value3 = Float(splitValues[3]) ?? Float("0.0")

All I am simplying trying to do is

if (value0 > scale0) {
    scale0 = value0
}

I am either faced with a: Binary operator '>' cannot be applied to operands of type 'Float?' and 'Float'

or (when I wrap the variables around Float(var) etc

Value of optional type 'Float?' must be unwrapped to a value of type 'Float'

Upvotes: 3

Views: 4132

Answers (1)

Martin R
Martin R

Reputation: 539845

All your valueX variables are optionals because Float("0.0") returns an optional. The possibility to compare optional and non-optional values directly was removed in Swift 3 because its semantics are unclear, and it could lead to surprising results (see SE-0121 – Remove Optional Comparison Operators).

What you want is

let value0 = Float(splitValues[0]) ?? 0.0
// ...

so that the value is either the result of the conversion of splitValues[0] to a floating point value (if that represents a valid number), or zero.

Note that you code will still crash if the splitValues array contains less than 4 elements. Also characters is deprecated, and the conversion from Substring to String not needed:

let splitValues = message.split{$0 == " "}
if splitValues.count >= 4 {
    let value0 = Float(splitValues[0]) ?? 0.0
    // ...
}

You can also use

let values = message.split{$0 == " "}.map { Float($0) ?? 0 }

or

let values = message.split{$0 == " "}.compactMap(Float.init)

to convert the string to an array of floating point values directly. The first version replaces invalid numbers by zero, and the second version skips invalid numbers.

Upvotes: 4

Related Questions