TheYogi
TheYogi

Reputation: 1026

Optional generic parameters in Kotlin

Here's the current problem I'm trying to solve, we have the following interface in Kotlin:

interface Parent<out Result, in Params> where Result : Any {
    fun run(params: Params): Result
}

The issue here is that sometimes I don't want to pass any params to the interface so I end up passing Unit as the type parameter and the overriding class ends up looking like this:

class Child : Parent<String, Unit> {
    override fun run(params: Unit): String { ... }
}

End Goal: It would be nice to add some abstraction in order to "get" a run function with no Params at all when Params is Unit like:

class Child : Parent<SomeEntity, Unit> {
    override fun run(): Entity { ... }
}

Or even better, optionally pass the second type parameter in order to have a single class that take one or two type parameters.

class Child : Parent<String> {
    override fun run(): Entity { ... }
}

Same Parent class with params

class Child : Parent<String, Int> {
    override fun run(params: Int): String { ... }
}

Is this possible at all?

Upvotes: 1

Views: 1748

Answers (2)

Tenfour04
Tenfour04

Reputation: 93551

You can create an extension function that handles Parents where the second type is a Unit. The function will only be available for use when the second type is a match for Unit:

fun <Result> Parent<Result, Unit>.run() = run(Unit)

The terminology you're using is atypical. A class that implements an interface is not a child of that interface. It is a child of whatever its superclass is.

Upvotes: 3

gpunto
gpunto

Reputation: 2822

I don't think you can do anything special with a single interface. 🤷‍♂️
The one solution that comes to mind is creating a child interface with a single type parameter that overrides the Unit function delegating to a different one without parameters.
Something like:

interface Parent1<out Result> : Parent<Result, Unit> {
    override fun run(params: Unit): Result = run()
    fun run(): Result
}

Upvotes: 2

Related Questions