val result: Result<Unit> = runCatching { Result.success("fuu") }
This code compiles fine but I would expect it to fail because the return type from runCatching
is Result<String>
and not Result<Unit>
. Is compiler so smart that it knows that I don't care about actual return type because I specified it as Result<Unit>
? Or it is some other feature of language? Is it described in some language design document? I couldn’t find any documentation on this.
The type of runCatching { Result.success("fuu") }
is Result<Result<String>>
. You can get a Result<String>
just with runCatching { "foo" }
. runCatching
is a generic function:
inline fun <R> runCatching(block: () -> R): Result<R>
Since you didn't specify its parameter type R
explicitly, it was inferred from the context. The context was that it needs to return a Result<Unit>
, so your line is equivalent to:
val result: Result<Unit> = runCatching<Unit> { Result.success("fuu") }
This means that the block
argument (the lambda expression) that you pass to runCatching
needs to be of type () -> Unit
; therefore, the result of Result.success
is discarded, and the object Unit
is returned instead.
Note that the following would indeed give you the type of error you were expecting:
val temp = runCatching { Result.success("fuu") }
val result: Result<Unit> = temp
In the above, the type of temp
is inferred to be Result<Result<String>>
and this cannot be cast to Result<Unit>
.