Kotlin currently does not support type parameters on enums, but it would be useful to have them.
There has been some discussion here from people missing the same feature in Java:
Could this be possible in Kotlin?
Kotlin currently does not support type parameters on enums, but it would be useful to have them.
There has been some discussion here from people missing the same feature in Java:
Could this be possible in Kotlin?
Do you have a good use-case?
The problem I see is that if you manipulate an enum member through the enum type, you canāt access the type parameter.
So you only get access to it when you manipulate the enum member by name. But then you can āharcodeā the parameter everywhere it is used.
That leaves extending a generic class with different parameters for different enum members. That is indeed Lukasā exemple:
public interface DataType<T> {}
public enum SQLDataType<T> implements DataType<T> {
TINYINT<Byte>,
SMALLINT<Short>,
INT<Integer>,
BIGINT<Long>,
CLOB<String>,
VARCHAR<String>,
...
}
But thatās only the definition. How to use that usefully?
Iād say SQLDataType is a very good use-case example, as it is directly from jOOQ.
An example of how that is useful: in jOOQ, a query result object has the following method:
<T> Field<T> field(String name, DataType<T> dataType)
So you could use result.field("name", SQLDataType.VARCHAR)
to actually get a string,
or result.field("id", SQLDataType.INT)
to get an int, etc.
Maybe itās better to use sealed class hierarchy in such case?
sealed class SQLDataType<T : Any>(val datatype: KClass<T>) {
object TINYINT : SQLDataType<Byte>(Byte::class)
object SMALLINT : SQLDataType<Short>(Short::class)
// etc
object VARCHAR : SQLDataType<String>(String::class)
}
That would be better than using normal class hierarchy, but I think sealed classes are not really suitable if you just need a fixed set of objects. For example, with sealed classes you canāt iterate all its objects, or get an objectās ordinal.
Enums would be perfect for these cases, but for some unknown reason Java and Kotlin do not allow type parameters on them. Could it be done, or is there a reason itās not possible?
I know itād be tedious to implement for a lot of instances, but you could add an iterative accessor, ordinal accessor, and some other stuff (i.e. valueOf or something) manually. Not a great solution of course, but it could serve as a workaround at least.
I REALLY WANT THIS!!
consider this enum:
enum class Conjunction(private val pred: (Predicate<Any>, Predicate<Any>) -> Predicate<*>) : (Predicate<Any>, Predicate<Any>) -> Predicate<*>
{
AND({ p1, p2 -> p1.and(p2) }),
OR({ p1, p2 -> p1.or(p2) });
override fun invoke(p1: Predicate<Any>, p2: Predicate<Any>) = pred(p1, p2)
}
Absence of type parameters makes it basically unusable. Could I use type Parameters, then I would replace Any with T, but I canāt, so I have to resort to a normal class nowā¦
No news on this? It still bugs me regularlyā¦
Right, you donāt have ordinals like in enums, but it is possible to iterate sealed objects:
private sealed class SealedValue {
object A : SealedValue()
object B : SealedValue()
object C : SealedValue()
}
fun main() {
val sealedValues = SealedValue::class.sealedSubclasses.mapNotNull { it.objectInstance }
sealedValues.forEach(::println)
}
To have a logically related iterable set of objects (without having to use reflection) I just wrote the following helper base class:
open class EnumObjectList<T> private constructor( private val list: MutableList<T> ) :
List<T> by list
{
constructor() : this( mutableListOf() )
protected fun <TAdd : T> add( item: TAdd ): TAdd = item.also { list.add( it ) }
}
Which for example can be used as follows:
object SamplingSchemes : EnumObjectList<DataTypeSamplingScheme<*>>()
{
val GEOLOCATION = add( Geolocation( TimeSpan.fromMinutes( 1.0 ) ) )
val STEPCOUNT = add( Stepcount( TimeSpan.fromMinutes( 1.0 ) ) )
}
The members retain their full type information, and there is no need for an āintermediateā enum type.
I wrote the full reasoning behind this up in a blog post: List of Strongly-Typed Objects Acting Like Enum in Kotlin ā whatheco.de
My personal opinion very much instersects with what @Whathecode says. Antlr (Parser Generator) for example makes heavy use of that to prevent reflecting over types. So, parsers would be a good use case I guess.
Also I think that would be a very usable feature for when statements and pattern matching.
So primary purpose is probably reducing reflecting code. Which is great for native, too, no?