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

  1. we have no sum-types in kotlin, no way tell compiler expect int or double or float , nothing else
  2. if library-method expects pair<string, *>, there no way tell compiler, want able give string 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

Popular posts from this blog

ios - MKAnnotationView layer is not of expected type: MKLayer -

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -