The line `return@tryLambdas` should throw an error...
# announcements
s
The line
return@tryLambdas
should throw an error here right? It does if i make it return
String
directly instead of generics. not sure what is going on here, could this be cause of type erasure?
Copy code
inline fun T tryLambdas(lamb : () -> T) : T{
    return lamb.invoke()
}

fun main() {
    tryLambdas<String>{
        return@tryLambdas // this should throw an error, but it doesnt. on decompiling it replaces it with Unit.INSTANCE
    }
}
k
I think it compiles to
tryLambdas<Unit>
which is a valid lambda
s
yes, even i thought so, but it even accepts
String
. like i can return
return@tryLambdas "some value"
k
The type is infered from the lambda. Return value of lambda determines what gets insterted as
T
So if you do
return "someString"
, then
T
is
String
. Btw, you can omit
return
statement, and write just
tryLambdasString { "someString" }
because result of last lambda's expression is the return value of lambda
Does that makes sense?
s
that's not what my problem is, the problem is i wish to perform a non-local return as well. which it does, but it also allows to return without conforming to the return type specified? which in this case is
String
. so i can not return a string from a lambda which was specified to return a string. worst, i can return a string or return nothing (unit.)
are you getting it?
k
Do you want to restrict the return type of lambda, or do you want to force
tryLambdas
to return if you do return from lambda?
Or is it something else? A more elaborate example would help
s
yes, the former. i wish to restrict the lambda to return the type im specifying in
T
.
k
The problem is that you don't specify
T
, it gets inferred
tryLambdasString<Unit> { "string" }
won't compile. Is this what you want?
Otherwise, you must specify type in function signature:
Copy code
inline fun tryLambdas(lamb : () -> Unit) : Unit {
    return lamb.invoke()
}
Or, you could restrict T, e.g.
Copy code
inline fun <T: String> tryLambdas(lamb : () -> T) : T{
    return lamb.invoke()
}

tryLambdas {
    5 // does not compile, must be a String
}
s
but it might not always be a String or a Unit or something that extends a String.
there was a typo in the original question, my bad, ive updated it.
k
I don't know of a way to restrict type without restricting it
s
so,
Copy code
tryLambdas<String> {
 // allows both
return@tryLambdas "string"
// and this, which is unit, 
return@tryLambdas 
}
even though im specifying
T
as
String
the latter one, which is just
return@tryLambdas
should throw an error right? the lambda should expect a
String
.
k
Yeah, you're right, it should not compile
It's a bug in new compiler type inferrence. It would be nice if you reported it
s
okay. i'll do it. thanks.
k
For now, you can disable the new compiler by unchecking the checkbox
Enable new type inference ...
, as shown in the screenshot
s
let me try. give me a moment.
yes it works. seems like a bug. good catch. i'll report it.
k
👍
s
thanks @faisalahmed for the tip.
👍 1