janvladimirmostert
07/05/2020, 12:45 PMAny?
, treat a non-valid expression on its last line as Unit instead of complaining that non-valid-expression is not Any?
See the example below:
inline fun foo(action: String = "Unknown", f: (bar: String) -> Any?): String {
f("TESTING")
return "DONE"
}
This currently works
fun doSomething() {
var k : Int = 0;
foo(action = "DoSomething") {
// Empty lambda's return type seen as Unit
}
}
This too works
fun doSomething() {
var k : Int = 0;
foo(action = "DoSomething") {
k++ // return type seen as Int
}
}
This doesn't work
fun doSomething() {
var k : Int = 0;
foo(action = "DoSomething") {
k = k + 1 // <<--- "Expected a value of type Any?"
}
}
Workaround
fun doSomething() {
var k : Int = 0;
foo(action = "DoSomething") {
k = k + 1
"Garbage value to please compiler" // now it compiles fine, return type seen as String
}
}
Also see the comment on YouTrack
Concerning Unit, 6.6.3 of spec says - "...This type may be used as a return type of any function that does not return any meaningful value." I think lambdas and blocks whose last statement is an assignment qualify as not returning any meaningful value.
https://youtrack.jetbrains.com/issue/KT-20215Derek Peirce
07/05/2020, 8:35 PMf
to (String) -> Unit
, is there a particular reason you need Any?
instead?Kroppeb
07/06/2020, 6:11 AMUnit
janvladimirmostert
07/06/2020, 2:20 PMval results: List<Result> = transaction {
it.selectTenRowsOfSomething()
}
val results: Int = transaction {
it.countSomething(...)
}
var recordsChanged = 0
transaction {
recordsInserted += it.insertSomething()
recordsInserted += it.insertSomethingElse()
// now forced to put a Unit hack here that looks totally inconsistent with the other examples
Unit
}
There are some DSL use-cases as wellDico
07/06/2020, 9:19 PMjanvladimirmostert
07/07/2020, 3:22 PMfun <T> foo(block: () -> T): T {
return block()
}
var a = 0
foo {
a += 1
}
val result = foo<String> {
"blah"
}
both works doing it this wayval result = foo {
"blah"
}
so that works toofun <T> foo(action: String = "Unknown", f: (bar: String) -> T): T {
return f("TESTING")
}
var a = 0
val result1: Unit = foo {
a += 1
}
val result2: String = foo {
"blah"
}
that seems inconsistentval result1: Any = foo {
a += 1 <<-- doesn't compile
}
that a += 1
returns Unit. As far as i'm aware, Any contains Unit, but not in the above example
println(Unit is Any) ---> prints true
Dico
07/08/2020, 12:00 PMvoid
in jvm compilations. Any
is interpreted by the compiler is saying "I will return a value" whereas Unit is used in place of voidAny
here, but you can explicitly override it to be Unit
. There are good reasons for Any to be inferred, it allows you to easily widen a more concrete type so you can later assign other subtypes.janvladimirmostert
07/08/2020, 12:04 PMUnit is Any
outputs true