In java I have a method:
public <T extends Relay, F extends Function<String, T>> T make_relay(Class<F> clazz, String name, Consumer<F> block) {
F builder = clazz.getConstructor().newInstance();
block.accept(builder);
T relay = builder.apply(name);
relay.setPlugin(this);
register(name, relay);
return relay;
}
it is a dsl method which produces instances of some specific derived class that inherits interface Relay
.
I have a bunch of this builders, say FooRelayDsl
, BarRelayDsl
, etc
This builders have their own sets of methods.
So I pass this specific builder class into method make_relay
along with name and a lambda block, that contans actual dsl method calls which parameterize the builder and then that builder being fired to produce an instance of Relay
’s heir class.
And it returns that created instance of Relay
.
I can use it like this:
val foo: FooRelay = make_relay(FooRelayDsl::class.java, "some_name") { builder : FooRelayDsl ->
builder.set_some_foo_callback { TODO() }
builder.set_some_foo_variant("foo1")
}
Now I want to make kotlin’s inline fun
to make it prettier.
First attempt:
inline fun <T : Relay, reified F : java.util.function.Function<String, T>> RelayMaker.makeRelay(name: String, noinline block: (F) -> Unit): T {
return this.make_relay(F::class.java, name, block)
}
but it requires two type params
val fooRelayInstance = makeRelay<FooRelay, FooRelayDsl>("name") { it.set_some_foo_variant("foo1") }
Second attempt:
inline fun <reified F : java.util.function.Function<String, T>> RelayMaker.makeRelay(name: String, noinline block: (F) -> Unit): T
where T : Relay {
return this.make_relay(F::class.java, name, block)
}
it does not work. it does not know what T
is cause it appear only in where and inside other type declarations
Is it possible to have only one type param and make it work?