https://kotlinlang.org logo
#announcements
Title
# announcements
s

Suraj Shah

07/19/2019, 3:23 PM
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

Karolis

07/19/2019, 3:52 PM
I think it compiles to
tryLambdas<Unit>
which is a valid lambda
s

Suraj Shah

07/19/2019, 5:03 PM
yes, even i thought so, but it even accepts
String
. like i can return
return@tryLambdas "some value"
k

Karolis

07/19/2019, 5:09 PM
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

Suraj Shah

07/19/2019, 5:13 PM
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

Karolis

07/19/2019, 5:16 PM
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

Suraj Shah

07/19/2019, 5:19 PM
yes, the former. i wish to restrict the lambda to return the type im specifying in
T
.
k

Karolis

07/19/2019, 5:19 PM
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

Suraj Shah

07/19/2019, 5:24 PM
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

Karolis

07/19/2019, 5:25 PM
I don't know of a way to restrict type without restricting it
s

Suraj Shah

07/19/2019, 5:26 PM
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

Karolis

07/19/2019, 5:27 PM
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

Suraj Shah

07/19/2019, 5:29 PM
okay. i'll do it. thanks.
k

Karolis

07/19/2019, 5:29 PM
For now, you can disable the new compiler by unchecking the checkbox
Enable new type inference ...
, as shown in the screenshot
s

Suraj Shah

07/19/2019, 5:30 PM
let me try. give me a moment.
yes it works. seems like a bug. good catch. i'll report it.
k

Karolis

07/19/2019, 5:30 PM
👍
s

Suraj Shah

07/19/2019, 5:40 PM
thanks @faisalahmed for the tip.
👍 1
2 Views