0

I am trying to do some math with user input numbers I get from UITextFields. The problem, there could be nothing in the TextField, in that case the value should be set to zero. I tried the guard statement but it seems I use it the wrong way:

    guard let number = numberTextField.text else{ let number = 0}

What is wrong with this code? What should I change?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Jan Mark Dannenberg
  • 603
  • 1
  • 7
  • 12
  • If there is nothing in the Textfield you wont get nil. numberTextField.text will be empty string "" – RajeshKumar R Sep 28 '17 at 17:06
  • @RajeshkumarR I'm looking at the documentation, and `UITextField`'s `text` property is optional. I don't know *why* it's optional, but it's in the docs... – Charles Srstka Sep 28 '17 at 17:08
  • @CharlesSrstka Yes. UITextField's text property is optional. But you'll never get nil even if you assign nil to the text property. So no need to use if let or guard for unwrapping the text. – RajeshKumar R Sep 28 '17 at 17:12
  • @RajeshkumarR Intuitively, it does seem that the property should never contain `nil`. However, presumably the development team found some edge case where it can return `nil`, or else they wouldn't have marked it as optional. In any case, it's easy enough to provide a default value using the `??` operator. – Charles Srstka Sep 28 '17 at 17:13
  • @CharlesSrstka Check this [link](https://stackoverflow.com/a/42861357/7250862) – RajeshKumar R Sep 28 '17 at 17:20
  • @RajeshkumarR It's still optional, though, and the compiler still won't let you use it without unwrapping it. Even the answer you linked to recommends using `??` to unwrap. – Charles Srstka Sep 28 '17 at 17:22
  • @CharlesSrstka Yes. I agree. But `let number = Int(numberTextField.text!) ?? 0` is enough I guess. Why we need to use `flapMap`? – RajeshKumar R Sep 28 '17 at 17:25
  • @RajeshkumarR The force-unwrap operator is very ugly when there's a simple alternative. Plus, the author of the answer you linked to doesn't seem to be an Apple employee, and I'm a bit hesitant to accept that something will *never* happen from someone who doesn't have access to the source code (plus, making it nil just for setting makes no sense. Even if the Objective-C property can be set to `nil` when `@""` would be perfectly fine, it doesn't mean the Swift version needs to do that). Just unwrap, it's easy. If you don't like `flatMap`, you can just `Int(numberField.text ?? "") ?? 0`. – Charles Srstka Sep 28 '17 at 17:44

3 Answers3

4

The guard statement cannot be used, because it requires you to exit from the function if the condition is false. Instead, you should use the ?? operator:

let number = numberTextField.text.flatMap { Int($0) } ?? 0

Why flatMap? Because we need to convert the String to an Int (or a Double, if this may contain a floating-point value) in order for it to be the same type as the 0. flatMap on an optional returns the value inside the closure if text is not nil, but returns nil if it is. In either case you'll end up with an optional Int, which is then made non-optional by supplying the default value of 0 via the ?? operator.

Charles Srstka
  • 16,665
  • 3
  • 34
  • 60
  • 1
    FYI - `guard` requires you to exit the block the guard is in. Of course if the guard is at the top of the function, it means you must exit the function. But not all guards are at the top of a function. – rmaddy Sep 28 '17 at 17:22
0

You'll want to use a default value instead of a guard to get the behavior you desire.

let number = Double(numberTextField.text) ?? 0
Blake
  • 122
  • 1
  • 7
  • I'm not sure why this got down voted. Seems like its the correct solution. Operator ?? is the same as saying "numberTextField.text != nil ? numberTextField.text! : 0" – David Neiss Sep 29 '17 at 17:17
  • I'm not sure either. – Blake Sep 29 '17 at 17:51
  • The problem with this is that the types don't match. What type is `number` after this code executes? Is it a number or a string? – ryantxr Sep 29 '17 at 19:06
-1

Nothing means empty string rather than nil "guard let" is used to check nil value

Let try the method below

if numberTextField.text.isEmpty {
   let number = 0
}
Tung Nguyen
  • 104
  • 1
  • 2