very new to Kotlin and trying to make some of my API work in Kotlin without changing API much.
I have a method, let's call it client
that receives a validation
function. There are two variants of Validation
. One that only suppose to do a validation, and the other can also return a value. To streamline user experience, in Java, I exposed two variants of the method. And it works as expected as I believe Java distincts between void
and Object
(<R>).
When I use my code in Kotlin, it can't distinct between two and I need to provide an explicit cast.
To remove Java from equation, I tried to replicate the situation in Kotlin using functional interfaces:
fun interface KotlinValidator {
fun validate()
}
fun interface KotlinValidatorWithReturn {
fun validateAndReturn(): Any
}
fun client(validator: KotlinValidator) {
println("validator NO return")
validator.validate()
}
fun client(validatorAndReturn: KotlinValidatorWithReturn): Any {
println("validator WITH return")
return validatorAndReturn.validateAndReturn()
}
fun test() {
val fromValidator = client {
100
}
val fromValidatorForced = client(KotlinValidatorWithReturn {
100
})
client {
}
}
it prints
validator NO return
validator WITH return
validator NO return
Based on my googling, it seems to be not possible to make it work without an explicit cast. However I hope that I am wrong as Groovy and Java let me do it.
To provide more context, I am trying to make WebTau HTTP module work nicely with Kotlin.
In Java and Groovy version I can do:
int id = http.post("/customers", customerPayload, ((header, body) -> {
return body.get("id");
}));
http.put("/customers/" + id, changedCustomerPayload, ((header, body) -> {
body.get("firstName").should(equal("FN"));
body.get("lastName").should(equal(changedLastName));
}));
In Groovy:
def id = http.post("/customers", customerPayload) {
body.id
}
But in Kotlin:
val id: Int = http.post("/customers", customerPayload, HttpResponseValidatorWithReturn { _, body ->
body.get("id")
})
The reason I brought this example is at the moment I am reluctant to change API and rename functions to distinct between the ones that return a value and the ones that don't.
The main problem is that in Kotlin, everything returns -- they may just return Unit
. There is no void
.
On the other hand, this may mean there is no need to distinguish between these types, you can just have the "with return" version.