scala - 如何获得与给定实例相同类型的空集合?

标签 scala reflection constructor

作为重写机制的一部分,我需要获取并执行与给定实例类型相同的集合构造函数。下面的代码总结了我的尝试。

import scala.reflect.runtime.universe.TypeTag
def getEmptyCollection[N : TypeTag](collection: N): N = {
  val runtime = scala.reflect.runtime.universe
  val mirror = runtime.runtimeMirror(getClass.getClassLoader)
  val classSymbol = runtime.typeOf[N].typeSymbol.asClass
  val classMirror = mirror.reflectClass(classSymbol)
  val constructorSymbol = runtime.typeOf[N].decl(runtime.termNames.CONSTRUCTOR).asMethod
  val constructorMirror = classMirror.reflectConstructor(constructorSymbol)
  constructorMirror()
}

val emptyList: List[Int] = getEmptyCollection(List(1, 2, 3))

但是,这段代码会产生一个实例化异常: 抛出 java.lang.InstantiationException

也许“typeOf[N]”是问题所在,但我只是猜测。您知道问题出在哪里吗?

谢谢!

最佳答案

正确的方法(在 Scala 2.12 中,在 2.13 中可能有些不同,而 2.11 将需要显式类型参数):

import scala.collection.generic.GenericTraversableTemplate
import scala.collection.GenTraversable

def getEmptyCollection[A, CC[X] <: GenericTraversableTemplate[X, CC] with GenTraversable[X]](collection: CC[A]) = 
  collection.genericBuilder[A].result()

println(getEmptyCollection(List(1, 2))) // List()
println(getEmptyCollection(Vector(1, 2))) // Vector()

不需要反射(reflection)!

关于scala - 如何获得与给定实例相同类型的空集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56447859/

相关文章:

Scala for ( ) vs for { }

java - 如何即时从类定义中删除方法?

generics - 存在主义和废弃你的样板

java - 拆分文件中的信息并读取它们

scala - 通过Spark Job Server运行作业

postgresql - 如何为 Play 2.0 设置 PostgreSQL?

scala - SBT和spark-submit之间在 yarn 上的Spark模式下运行Scala的不同行为

c# - 将对象转换为其他对象的类型

c# - 作为委托(delegate)的构造函数 - 在 C# 中是否可能?

C++ 静态变量声明奇怪的链接器错误