https://kotlinlang.org logo
#getting-started
Title
# getting-started
a

abbic

02/04/2022, 11:48 AM
hey, posting this here because i cant find a pure kotlin questions channel, what is the difference between, in a class, having
Copy code
Class {
    fun foo() { // normal method definition }
    val foo = { // same method implementation, but its a lambda }
}
t

therealbluepandabear

02/04/2022, 11:58 AM
In terms of behaviour, the end result is the same for both 🙂 Although the bytecode is slightly different.
Obviously you already know, but the first 'foo' is a function and can't be treated as an object, while the other foo is a property and can be treated the same as any other class property - while the function cannot. This means you could pass the lambda foo to a function, while you couldn't pass the function version of it.
a

abbic

02/04/2022, 12:03 PM
you could always pass it via method reference
::
! but yeah, i guess apart from readability i wondered if there were important cases where you might find a method was necessary over a val. i suppose that, if fancy took you, you might never need to define functions with
fun
at all! though it probably incurs some small overhead if i had to guess
t

therealbluepandabear

02/04/2022, 12:06 PM
I don't know, I personally would just use a regular function as it's more readable and clear.
And yes, you're right about the method reference 🙂
g

gildor

02/04/2022, 12:13 PM
fyi it's the correct channel for such questions 👍
1
t

therealbluepandabear

02/04/2022, 12:13 PM
In case you're wondering, here's the difference in how it's compiled:
Copy code
class FooClass() {
    fun fooFunc() {
        println("hi")
    }
    val fooLambda = {
        println("hi")
    }
}
Copy code
import kotlin.Metadata;
import kotlin.jvm.functions.Function0;
import org.jetbrains.annotations.NotNull;

public final class FooClass {
   @NotNull
   private final Function0 fooLambda;

   public final void fooFunc() {
      String var1 = "hi";
      boolean var2 = false;
      System.out.println(var1);
   }

   @NotNull
   public final Function0 getFooLambda() {
      return this.fooLambda;
   }

   public FooClass() {
      this.fooLambda = (Function0)null.INSTANCE;
   }
}
r

Roukanken

02/04/2022, 12:16 PM
null.INSTANCE
? I mean I haven't met much with bytecode stuff, but that sounds iffy
t

therealbluepandabear

02/04/2022, 12:19 PM
Yeah, it's strange. Do you also get it when you decompile it?
j

Johann Pardanaud

02/04/2022, 1:19 PM
you might also have some differences when using reflexion however, when calling, I don’t think you will notice any difference between the method and the lambda
r

Roukanken

02/04/2022, 1:31 PM
the only bit of difference in usage I thought of is this:
Copy code
data class Test(val value: Int) {
    fun plus1(other: Test) = Test(value + other.value) 
    val plus2 = { other: Test -> Test(value + other.value) }
}

fun main() {
    val tests = (1..5).map { Test(it) }
    
    println(tests.reduce(Test::plus1))
    println(tests.reduce { a, b -> a.plus1(b) })
    // println(tests.reduce(Test::plus2))
    println(tests.reduce { a, b -> a.plus2(b) })
}
the commented line does not work, because
(Test::plus1)(a, b)
==
(Test::plus2)(a)(b)
🦜 1
t

therealbluepandabear

02/04/2022, 2:19 PM
That's really interesting! 😄
2 Views