I have a function that assembles a URL with GET parameters, and it takes a parameter name of type String
and currently a parameter value of type Any?
on which it calls toString()
if not null
.
I want it to work only for types which can be meaningfully put into a URL (numbers, strings and booleans), and prevent people from calling it with any other object type.
Is this possible in Kotlin?
The usecase is that I tend to forget converting units to numbers when calling this function, and end up with param=Angle(30,DEGREES)
where I really want param=30
.
CodePudding user response:
If it is just a single function, you can use overloads for this:
private fun yourFunction(param: Any?){
//your code
}
fun yourFunction(param: String?) = yourFunction(param as? Any?)
fun yourFunction(param: Int?) = yourFunction(param as? Any?)
fun yourFunction(param: Boolean?) = yourFunction(param as? Any?)
//the same for other types
At first, create your function with Any?
as you already do but make it private.
For every allowed type, add an overload with that type. That overload just calls the Any?
-overload.
If Union types are available in some future Kotlin version, you could use those as @Tenfour04 mentioned in the comments of your question but Union types are not a Kotlin feature at the time of writing.
CodePudding user response:
You can only have one upper bound for a generic type. Meaning that String OR Number
is not possible as of time of writing.
@dan1st pointed out that Union types may be the preferable solution to your problem.
However you can use these attempt to solve your issue:
Createing overloading method signatures where every type can be handled
fun makeUrl(path: String, parameter: String): MyUrl = downstreamUrlBuilder(path, parameter) fun makeUrl(path: String, parameter: Number): MyUrl = downstreamUrlBuilder(path, parameter.toString())
Creating a data access object that contains useful url information.
data class UrlParameter(val value: Any?) { init { if(value !is String && !is Number) throw IllegalArgumentException("reason") } } fun makeUrl(path: String, parameter: UrlParameter): MyUrl { TODO() }