7

I am trying to understand the reflection. I have the following code:

fun main(args: Array) {
println(lengthL1())
println(lengthL2(s))
println(lengthL1.get()) // Error
println(lengthL2.get(s)) // Error

println(lengthNL1.get())
println(lengthNL2.get(s))
println(lengthNL1())
println(lengthNL2(s))
}

val s = “1234”

val lengthL1: () -> Int = s::length
val lengthL2: (String) -> Int = String::length

val lengthNL1 = s::length
val lengthNL2 = String::length

Why I cannot call the get (See Error comments) when I declare the lambda? Is there any difference between lengthL1 and lenghtNL1?

LiTTle
  • 1,811
  • 1
  • 20
  • 37

1 Answers1

4

s::length is a property reference, which is an object of type KProperty1. The get method is defined as a member of this type.

If you declare a variable of a lambda type and initialize it with a property reference, you get a regular lambda (KFunction1). The KFunction1 interface declares only the invoke() method, allowing you to call it as lengthL1(), but it does not declare any additional methods such as get.

yole
  • 92,896
  • 20
  • 260
  • 197
  • I didn't expect that big change by only declaring the lambda type! Declaring types or not I thought that it would have no effect! – LiTTle Mar 07 '18 at 09:36
  • 3
    Well, if you declare `val x: Any = "abc"`, you also won't be able to access `x.length`, so I don't see why exactly this is surprising... – yole Mar 07 '18 at 09:41
  • I am changing the type! That never crossed my mind! Feeling embarrassed! – LiTTle Mar 07 '18 at 10:16