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 givestring
instead 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