https://kotlinlang.org logo
Title
j

Jonathan Mew

08/27/2021, 2:48 PM
Couple of
value class
queries 🧵
We currently have some "Microtype" classes which wrap a single value. So for example we have a StringMicrotype abstract class extended by a bunch of others. I was exploring the possibility of migrating to inline/value classes instead.
I've hit 2 issues so far: • We have some string types we effectively would like to be case-insensitive. I think I'd need to do something like call a companion
MyCaseInsensitiveString.new(s)
and pass the lowercased string to a private constructor to preserve that logic. • We have Exposed Column Types related to our Microtypes - so we have an
abstract class StringMicrotypeColumnType<T: StringMicrotype>
extended by a few others, each associated with the relevant Microtype (e.g.
EmailColumnType
associated with
Email
). Is there a way to use generics to refer to "any value class that contains a String value"?
Perhaps these types are legitimately better as non-value classes - I'm not bothered about improving performance, just thought it might mean less/more concise code.
@JvmInline
value class EmailAddress private constructor(val value: String) {
    companion object {
        fun new(value: String): EmailAddress = EmailAddress(value.lowercase())
    }
}
(the microtypes are pretty concise already - this would mainly just cut out some class hierarchy)
s

Stephan Schroeder

08/30/2021, 6:57 AM
• I like your value class with factory method 👍 • I'm fairly certain that there's no way to use generics to accept any value class containing a String (since this is basically the opposite of what you'd normally want @JvmInline value classes for: more type-safety) But you could maybe implement an Interface on your value classes and use that!?
interface StringContainer {
  fun getContent(): String
}
j

Jonathan Mew

08/31/2021, 7:46 AM
looks like I might get away with
interface StringContainer {
  val value: String
}

@JvmInline
value class EmailAddress private constructor(override val value: String): StringContainer {
...
}
Not sure it's worth it though 🤔 Thanks for the input!