简体   繁体   中英

confused with the functionality of `return` in swift

I am confused with return in Swift. I understand it's used to return the value in a function, if used like this:

func double(value: int) -> Int { 
    return value * 2
}

But I often just see return being used, like in a guard statement in an optional binding like this:

guard let value = value else (
    print ("nothing")
    return
}

So what is the purpose of having just return in the guard statement like this? Actually, I often see this not only in guard statements when unwrapping optional values. I always find this problem when writing code, when I want to use an optional string from a dictionary.

let info = ["name": "sarah", "hometown": "sydney"]

class UserInfo {

    func getTheName() -> String {
        guard let name = info["name"] else { return }

        return name
    }
}
// Compile time error: "Non-void function should return a value"

I get this error even though I have written return name . Xcode still complains that I have not returned a value. Is it because of the return in the guard statement?

So, could you please tell me the purpose of return in Swift? It is confusing for me.

return without any argument returns Void . This form of the return statement can only be used with a function that returns Void .

Once the return statement executes, the function exits and no more code in your function executes. Since you have a return in the guard statement, the second return name won't be executed (it couldn't anyway since it wouldn't have a name to return), which is why you get a compiler error; the compiler looks at all of the paths that your function could take to return something and ensures that all of those paths return what the function signature says it will.

The function in your question states that it returns a String , so you can't simply say return in the guard statement as that returns Void , violating the contract expressed by your function signature.

You could return a default value that isn't Void :

func getTheName () -> String {
    guard let name = info["name"] else {
        return ""
    }
    return name
}    

This could be written much more succinctly using the nil-coalescing operator ; return info["name"] ?? ""

You can also use return in a function that returns Void (or has no explicit return type, in which case it is implicitly understood to return Void )

So you could have a function like:

func maybePrint(theMessage: String?) -> Void {
    guard let msg = theMessage else {
        return
    }
    print(msg)
}

You're on the right track.

In your guard statement inside getTheName(), the 'return' keyword will try to exit the function itself if the guard fails. But the function requires you to return a String and as such you get the compiler error.

Here is a portion of another SO answer to a similar question:

guard forces you to exit the scope using a control transfer statement. There are 4 available to you:

return and throw both exit the function/method continue can be used within loops (while/for/repeat-while) break can be used in loops (while/for/repeat-while) to exit the immediate scope. Specifying a label to break to will allow you to exit multiple scopes at once (eg breaking out of nested loop structure). When using a label, break can also be used in if scopes. Additionally, you may exit the scope by calling a function that returns Never, such as fatalError.

Stack Overflow: If the Swift 'guard' statement must exit scope, what is the definition of scope?

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