简体   繁体   中英

How to use optional binding in Swift 2

I'm new to learning Swift so I decided I might as well learn Swift 2 instead. Everything has made sense to me so far except for the following code snippet. Hopefully someone can shed some light on this for me.

//: Playground - noun: a place where people can play
import UIKit

//Works
let possibleNumber="2"
if let actualNumber = Int(possibleNumber) {
    print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
}
else {
    print("could not be converted to integer")
}

//Doesn't Work and I'm not sure why
let testTextField = UITextField()
testTextField.text = "2"
let numberString = testTextField.text  //I know this is redundant

if let num = Int(numberString) {
    print("The number is: \(num)")
}
else {
    print("Could not be converted to integer")
}

The top section of the code is straight from Apple's Swift 2 ebook and it makes sense to me how it uses optional binding to convert the string to an int. The second piece of code is basically the same except that the string comes from the text property of a UITextField. The bottom part of the code gives the following error:

I fixed the problem by using this line:

if let num = Int(numberString!) {

I just want to know why the second example needs the ! and the first doesn't. I'm sure the problem has to do with the fact that I'm getting the string from a textfield. Thanks!

The difference is that in the first case possibleNumber is not an optional variable. It is definitely a string. It cannot be nil.

In the second case textField.text returns an optional string and so numberString is an optional variable. It could be nil.

Now... The conversion Int("") returns an optional int. if the string is "abc" then it cannot return a number so returns nil. This is what you are unwrapping with the if let... statement.

However, in the second case your string is also optional and the Int() will not accept an optional. So you are force unwrapping it. This is dangerous as it could crash the app if the string is nil.

What you could do instead is this...

if let numberString = textFeidl.text,
    number = Int(numberString) {
    // use the number
}

This will unwrap the text first and if it's available then use it to. Get the number. If that is not nil then you enter the block.

In Swift 2 you could use the guard let function here also.

Just seen that you are using Swift 2.

You can do it this way also...

func getNumber() -> Int {
    guard let numberString = textField.text,
          number = Int(numberString)
          else {
          return 0
    }

    return number
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM