kotlin - Can we achieve compile-time type safety for a union of types we can't control? -
let's have function:
fun dosomething(vararg pairs: pair<string, *>) { // things pairs } the problem approach allows type second half of pair (e.g. pair<string, customtype1>).
what if want allow finite number of types, how achieve that?
if function had simpler signature, achieve restriction via overload, so:
fun dosomethingsimpler(param: boolean) { // boolean implementation } fun dosomethingsimpler(param: int) { // int implementation } // etc. if restricted type "set" in control, use interface or sealed class achieve this. e.g.
sealed class root class child1 : root() class child2 : root() fun dosomethingicancontrol(param: root) { // root implementation } yet if don't have control on types or primitive, how prevent * allowing through?
i know use smart-casts run-time safety, can done @ compile time?
or language disallow it?
edit 1
i know create own box types (e.g. myboolean) , use common interface or sealed class, boilerplate have write every time needed to.
edit 2
to clear, i'd able make invocation so:
dosomething( "key1" false, "key2" "value2", "key3" 86 ) ... i.e. have mixed set of "second" (of pair) types.
so sum up:
you want call methods library expects pair<string, *>, limit possible values * can be.
tl;dr: trying accomplish not possible without kind of wrapper, because
- we have no sum-types in kotlin, no way tell compiler expect int or double or float , nothing else
- if library-method expects
pair<string, *>, there no way tell compiler, want able givestringinstead of*
one way behaviour create decorator (decorator pattern), e.g. create own extension methods allow subset
class foo { //allows fun dosomething(param: pair<string, *>) } //now lets create our own extension methods fun foo.dosomethingwithint(param: pair<string, int>) fun foo.dosomethingwithboolean(param: pair<string, boolean>) fun foo.dosomethingwithstring(param: pair<string, string>) or if dont want able call foo.dosomething() can create decoractor-class:
class foodecorator { val foo = foo() fun dosomething(param: pair<string, int>) { } } and following example not possible without kind of wrapper, because there no sum-types in kotlin:
dosomething( "key1" false, "key2" "value2", "key3" 86 ) what like:
at first, create own jsonitem type , add extension-methods types can used one
class jsonitem<t> private constructor (item: t) fun int.asjsonitem() = jsonitem(this) fun string.asjsonitem() = jsonitem(this) fun boolean.asjsonitem() = jsonitem(this) then able that:
//your own personal dosomething fun dosomething(varargs: param: pair<string, jsonitem>) { //call real dosomething() dosomething(param.map { pair(it.first, it.second.item) }} } dosomething( "key1" false.asjsonitem(), "key2" "value2".asjsonitem(), "key3" 86.asjsonitem() )
Comments
Post a Comment