scala - Why do Arrays require ClassTags but collections like List do not? -
this works fine:
def x[a](a: a) = list(a) no classtag available a:
def y[a](a: a) = array(a) but of course of study kosher:
def y[a : classtag](a: a) = array(a) what gives?
arrays preserve type @ runtime, generic methods lose genericity @ runtime due type erasure. so, if you're dynamically creating array @ runtime generic method, generic type info has preserved. jvm not aware of type due erasure, scala keeps info around in form of classtag, allowing avoid erasure problem.
you cheat using java reflection
def y[a](a: a, length: int) = java.lang.reflect.array.newinstance(a.getclass, length) but terrible - note returned type object, not array[a], due erasure
scala> y("foo", 1) res2: object = array(null) also note java.lang.reflect.array.newinstance() returns object in api documentation.
this makes sense because java has erasure , doesn't have classtags.
scala has classtags, array created @ runtime can created appropriate type:
scala> def y[a : classtag](a: a) = array(a) y: [a](a: a)(implicit evidence$1: scala.reflect.classtag[a])array[a] scala> y("foo") res4: array[string] = array(foo) scala> y(1) res5: array[int] = array(1) learn more type erasure on jvm here (java examples):
erasure of generic types erasure of generic methods erasure of bridge methods non-reifiable typesof course, due erasure, list of becomes list of anyref @ runtime, long type checking validated @ compile time (via generics), jvm doesn't care @ runtime types when generic object instantiated.
scala collections
No comments:
Post a Comment