https://kotlinlang.org logo
Title
j

Joshy Josh

12/04/2020, 11:19 PM
Is there a simple way to create a generic type-safe builder that can be used with a lambda? like
functionName<ClassName> { …className functions}
? I know it can be done specifically, but I was wondering if there was a way to create a generic approach. in Kotlin.
More specifically, where ClassName could be any class passed in the the type.
I started with this:
interface BaseRobot {
    fun <T> screen(init: T.() -> Unit): T = init as T
}
It allows to call, but then when using it will perform a cast error or do nothing with no error.
s

Shawn

12/05/2020, 12:36 AM
what exactly are you trying to accomplish with this?
j

Joshy Josh

12/05/2020, 12:38 AM
Basically have a generic way to call object members using a lambda notation,
screen<class> { function() }
Typically, when I create object for this I have to specify the class in the function using a function outside of the class utilizing the type safe builder approach.
s

Shawn

12/05/2020, 12:39 AM
I mean, if you have an instance of the object in question, you could use
run
,
with
, or
apply
j

Joshy Josh

12/05/2020, 12:40 AM
I did try, but got a casting error.
s

Shawn

12/05/2020, 12:40 AM
care to be be more specific about the error?
with the limited context of “having a generic way to call object members with a lambda”
T.() -> R
is the correct approach, but casting the lambda to
T
will never work (at least the way you’ve written it in your example)
j

Joshy Josh

12/05/2020, 12:44 AM
I stepped away, so I don't have the exact error log, but it was saying I cannot cast type T to Unit. Basically, I was trying to make this function generic...
fun screen(bot: Bot.()-> Unit): Bot = Bot().apply(bot())
I was so close. Ended up using this:
Inline fun <reified T: Any> screen(bot: T.() -> Unit): T? = T::class.java.newInstance().apply { bot() }
Then I can use it like
screen<ScreenObject> { functionsFromScreenObjectClass }