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

Andrew Gazelka

07/12/2019, 6:25 PM
is there anyway to have something like this
Copy code
fun <T> wrapperFunc(block: (…) -> T): (…) -> T{
    println("wrapped")
    return block (…) -> T
}
and call it like
Copy code
val testFunc = wrapperFunc {
    fun(a: String) -> println("a is $a")
}

testFunc("abc")
🚫 1
l

Luke

07/12/2019, 6:31 PM
Do you want the call to print to be called when you run
testFunc("abc")
?
a

Andrew Gazelka

07/12/2019, 6:31 PM
yeah so
testFunc("abc")
would print to sout
Copy code
wrapped
abc
s

streetsofboston

07/12/2019, 6:35 PM
I don’t think that is possible without using reflection. The issue is the
...
, like a vararg kind a thing, but each argument should be individually typed (and on top of that, i think that lambdas can take a vararg).
a

Al Warren

07/12/2019, 6:36 PM
Not really the same but it might give you some ideas. I have an abstract class with this in it:
Copy code
internal var clickListener: (T) -> Unit = { }
Then the concreted class does this:
Copy code
setOnClickListener { clickListener(data) }
Finally, the calling class does this:
Copy code
adapter.clickListener = ::onItemClick
l

Luke

07/12/2019, 6:38 PM
You can have something like this: http://tiny.cc/fgwm9y. But yeah, you can’t be too general with parameters quantity and types
a

Al Warren

07/12/2019, 6:39 PM
Oh, sry, I didn't take the ellipses to actually mean varargs. Nevermind. 😁
b

bloder

07/12/2019, 6:42 PM
Maybe you can use other approach to that like compose your functions, actually is basically what you want there, no?
s

streetsofboston

07/12/2019, 6:56 PM
@Andrew Gazelka Something like this?
Copy code
infix fun <R> (() -> Unit).andThen(function: () -> R) : () -> R = {
    this()
    function()
}

infix fun <T1, R> (() -> Unit).andThen(function: (T1) -> R) : (T1) -> R = {
    this()
    function(it)
}

infix fun <T1, T2, R> (() -> Unit).andThen(function: (T1, T2) -> R) : (T1, T2) -> R = { t1, t2 ->
    this()
    function(t1, t2)
}

infix fun <T1, T2, T3, R> (() -> Unit).andThen(function: (T1, T2, T3) -> R) : (T1, T2, T3) -> R = { t1, t2, t3 ->
    this()
    function(t1, t2, t3)
}

fun prefix() {
    println("wrapped")
}

fun functionToWrap(name: String, age: Int): String = "$name has age $age"

fun main() {
    val testFunc = ::prefix andThen ::functionToWrap
    println(testFunc("Jim", 45))
}
But, yes, for the
vararg
like functionality, you’d need to define more and more
andThen
functions, each one an extra
Tn
generic parameter.
2 Views