How to create an object attribute from polymorphic type in scala -
i trying create object store instances object created , avoid re-load. tried create mutable map on object store it, compilation error.
this code:
class bar  class foobar extends bar  object foo {     val loaded = scala.collection.mutable.map[string, bar]()      def apply[t <: bar](implicit m: manifest[t]): t = {         val classname = m.tostring()         if (loaded.contains(classname)) {             return loaded(classname)         }         val instance = m.runtimeclass.newinstance().asinstanceof[t]         loaded(classname) = instance         instance     } }   but when try compile error:
error: type mismatch;  found   : bar  required: t        return loaded(classname)   there way create map dynamically , pass t? or solve differently?
your problem in returning loaded(classname) of type bar, not t required function type signature. unfortunately, cannot encode such dependence between types of map keys , values, @ least not standard map collection. have perform explicit cast. here working example:
import scala.reflect.classtag  class bar  class foobar extends bar  object test {   val classmap = scala.collection.mutable.map[class[_], bar]()    def getinstance[t <: bar : classtag]: t = {     val ct = implicitly[classtag[t]]     classmap ct.runtimeclass match {       case some(bar) => bar.asinstanceof[t]       case none =>         val instance = ct.runtimeclass.newinstance().asinstanceof[t]         classmap(ct.runtimeclass) = instance         instance     }   } }  object main {   def main(args: array[string]) {     println(test.getinstance[foobar])     println(test.getinstance[bar])     println(test.getinstance[foobar])   } }   note i'm using classtag instead of manifest because manifest deprecated. modern equivalent typetag, task classtag more enough.
update
here variants of code suggested @0__. first:
import scala.reflect.classtag  class bar  class foobar extends bar  object test {   val classmap = scala.collection.mutable.map[class[_], bar]()    def getinstance[t <: bar : classtag]: t = {     val ct = implicitly[classtag[t]]     classmap ct.runtimeclass match {       case some(bar: t) => bar       case none =>         val instance = ct.runtimeclass.newinstance().asinstanceof[t]         classmap(ct.runtimeclass) = instance         instance     }   } }  object main {   def main(args: array[string]) {     println(test.getinstance[foobar])     println(test.getinstance[bar])     println(test.getinstance[foobar])   } }   and second, best 1 imo:
import scala.reflect.classtag  class bar  class foobar extends bar  object test {   val classmap = scala.collection.mutable.map[class[_], bar]()    def getinstance[t <: bar : classtag]: t = {     val ct = implicitly[classtag[t]]     classmap.getorelseupdate(ct.runtimeclass, ct.runtimeclass.newinstance().asinstanceof[bar]).asinstanceof[t]   } }  object main {   def main(args: array[string]) {     println(test.getinstance[foobar])     println(test.getinstance[bar])     println(test.getinstance[foobar])   } }      
Comments
Post a Comment