Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin clarification about @ symbol and return postfixes

Tags:

I am confused about the meaning usage of the next syntax.

  1. What does exactly do placing the postfixes "async" and "lazy" after a "return"?

    return async
    
    return lazy
    
  2. What does the "@" symbol mean here?

    return@async
    
    return@lazy
    
    return@withContext 
    

About the "@" symbol, does it have a special naming in Kotlin? so I can better locate all the ways to use it in the documentation?

What is the difference between adding @ and not using it? so:

"return async" vs "return@async"
like image 827
API_1024 Avatar asked Mar 28 '21 08:03

API_1024


1 Answers

  1. What does exactly do placing the postfixes "async" and "lazy" after a "return"?

This is not special syntax in Kotlin with the specific words "async" or "lazy". So it is not really a "postfix for the return keyword". After a space, what follows the return is always the value that you want to return:

  • return 42 returns the value 42
  • return async returns the value of the expression async (which is probably a variable that has been declared earlier in the code)
  • return async { 42 } returns the value of the expression async { 42 }.

The meaning of the expression async { 42 } here is unrelated to the return in itself. You could see the same expression assigned to a variable for instance: val deferred = async { 42 }. async is simply a library function from the kotlinx.coroutines library (it's just my guess by the way, maybe the code you've seen declares variables/functions of this name, but it's hard to tell without more context). Have a look at the doc of the async function here if you're interested.

  1. What does the "@" symbol mean here?

The return keyword by default returns from the closest enclosing function declared with the fun keyword. Lambdas don't count, because they are not declared with fun.

Therefore, return-ing from inside a lambda will by default (without @) return from an enclosing function rather than just the "local" lambda (as opposed to what happens in Java). This is why we call them non-local returns.

Using a qualified return with a label (return@label) allows to change this default behaviour and specify what you want to return from explicitly. See the doc about return at labels, it contains many examples.

The specific examples you gave:

return@async
return@lazy
return@withContext 

would need a bit more context to understand them. But I assume that you have seen them used inside lambdas that are a parameter of async/lazy/withContext function calls. What follows the @ here is called an implicit label which tells the compiler that this return is supposed to return from this lambda instead of returning from the closest enclosing fun.

Other notes

Note that the @ symbol here is not an annotation like you could see elsewhere like @JvmDefault or @OptIn(...), it is instead a label reference.

Note that both a label and a return value can be combined: return@myLabel 42 returns the value 42 from the function qualified by the label myLabel.

like image 89
Joffrey Avatar answered Sep 19 '22 19:09

Joffrey