Ho, I am still wondering if it is possible to do this, for example, that a property can be type Int or String, and that its value can be assigned from either type, and used according to the assigned type.
Declaration: val name : String or Int
Asignation: name = R.string.demo // Use Int name = "Kotlin" // Use string
I was wondering if it is possible to do something similar, I appreciate your answers in advance.
Kotlin doesn’t have union types so can’t do (using pipe from typescript like syntax) var name: Int | String = 5.
You could use an Either class which might allow var name = Either<Int, String>(5) or something like that.
What’s your use case? If you’re making you’re own classes you may want to consider if a sealed class/interface is appropriate. If you’re really wanting a union of Int and String it may be a code smell that there’s a better design.
My use case is the following:
I am creating a utility library for android, in some cases I need to receive text values to display in views. To facilitate the process, I want to admit a string directly, which is the one that it would show to the user, but I also want the possibility of giving me the ID of the resource (which is integer) to obtain the string of the resources within the library.
For Example:
class DemoView {
var name: Any = "Example"
}
In this case, the user can assign as a string, so I use it directly, but if I assign it as Int I get the value of the resources:
fun show() {
val finalName = when(name){
is String -> name
else -> context.getString(name)
}
}
The downside is that Any will accept any other type of data, and I would like to restrict it to String and Int.
Another approach that I have thought of is the following
class DemoView {
private var name: Any = "Example"
fun setName(value: String) {
name = value
}
fun setName(value: Int) {
name = context.getString(value)
}
}
I don’t know if these approaches are the best, or if it can be done in a better way.
I think you’re on the right lines with your last approach.⠀You just need to fix it by giving your private name field the type String; after all, your setters all set it to a string, so you know it must contain a string — and if you give it that type, the compiler will know too.
Having a property with one type, and extra setter-type methods that convert from other types, is a fairly common pattern.
Another advantage is that if it can’t convert (e.g. if there’s no resource for a number), you can throw an exception (or whatever) in that setter, where it should be much easier to trace the cause.