Scala 2.10反射:从类型创建数组

Scala 2.10反射:从类型创建数组,scala,reflection,types,casting,scala-2.10,Scala,Reflection,Types,Casting,Scala 2.10,在新的2.10版本中,我很难翻阅Scala(有些稀疏?)的文档。在这种情况下,我从没有类型信息的源中递归读取数据。在阅读时,我知道预期的类型,因此我可以检查该类型是否与传入数据一致 我的问题是:当尝试检索具有类型参数的集合对象(例如数组[Int])时,如何使用预期的类型来确保读取的值的类型正确 到目前为止,我已经处理了由提供的代码,该代码允许您提取类型参数。我还了解了,以及如何使用它们来创建数组。因此,我的下一个想法是1)找到类型参数,2)从该类型创建一个数组,3)查看读取的数据是否适合无异常,

在新的2.10版本中,我很难翻阅Scala(有些稀疏?)的文档。在这种情况下,我从没有类型信息的源中递归读取数据。在阅读时,我知道预期的类型,因此我可以检查该类型是否与传入数据一致

我的问题是:当尝试检索具有类型参数的集合对象(例如
数组[Int]
)时,如何使用预期的类型来确保读取的值的类型正确

到目前为止,我已经处理了由提供的代码,该代码允许您提取类型参数。我还了解了,以及如何使用它们来创建数组。因此,我的下一个想法是1)找到类型参数,2)从该类型创建一个数组,3)查看读取的数据是否适合无异常,如下所示:

val paramType = paramInfo[Array[X]]  // Step 1: Find the X type parameter
val array     = Array[paramType](size) // Step 2: Can't use TypeTags#Type as a normal Java type...
// Step 3: Feed data into the array and hope for the best
// Step 4: Profit!
由于上面的
paramType
为我提供了类型,因此将该类型转换为类标记应该是一件简单的事情。但是这个答案让我很困惑

老实说,这个解决方案对我来说似乎有点混乱,但我还没有想出更聪明的办法。如果有其他解决方案,我洗耳恭听

提前谢谢

编辑:为了澄清这一点,我上面的例子应该说明我想从Array[Int](例如)中提取类型X,然后生成一个包含该特定类型的数组实例。希望这能让事情变得更清楚

编辑:也许需要进一步澄清(我真的说得那么不清楚吗?:-)。我想从数据源读取集合。我希望该集合使用正确的预期类型键入。假设我调用方法
readData
。因为我知道期望的类型,所以我给它一个期望类型的类型参数。例如,让我们假设Array[Int]。它可以是Array[String]或Iterable[Any],也可以是Null或其他任何形式。调用
readData
方法时,我希望将给定的预期类型(Array[Int])与从外部源读取的数据类型相匹配。如果找到的类型与预期类型相同(或子类型),我们可以强制转换并返回数据。如果不是,则引发异常,通知用户找到的数据不是预期的类型。总而言之:我如何调用
readData[Array[Int]]
工作

编辑:我通过创建一个数组[Any]来解决这个问题,检索期望的类型(上面的X)并迭代该数组,以查看元素是否与X的类型(或子类型)相同。如果是,我们可以安全地强制转换到数组[X]。在下面的例子中,预期的类型是用E表示的。我知道,这是相当粗糙的,但再次强调:我希望看到替代品

// Matches if the type of o corresponds (<:<) to the type of x
def verifyType(o : Any, x : Type) : Boolean = { ... } 

// Get the type of the array parameter (X)
val tpe = reflect.runtime.universe.typeOf[E] tpe match {  
  // The returned Type is not an instance of universe.Type - hence the cast              
  case TypeRef(_, _, args) => args.asInstanceOf[List[Type]] 
  case _ => throw new IllegalArgumentException("Could not find type parameters in type " + tpe)
} 

// Iterate the array and make sure the types match
val hasWrongType = array.exists(e => !verifyType(e, tpe))

if (hasWrongType) throw new Exception(...) // The types does not fit
else array.asInstanceOf[E] // We can safely cast
//如果o的类型对应,则匹配(抛出新的IllegalArgumentException(“在类型“+tpe中找不到类型参数”)
} 
//迭代数组并确保类型匹配
val HasErrorType=array.exists(e=>!verifyType(e,tpe))
if(hasErrorType)抛出新异常(…)//类型不适合
else array.asInstanceOf[E]//我们可以安全地强制转换

您实际上不需要Scala 2.10中的任何新功能来实现这一点,尽管您使用的是替换的
ClassTag
,而不是早期版本的
ClassManifest

def makeArray[T : reflect.ClassTag](length: Int): Array[T] = {
  val tTag = implicitly[reflect.ClassTag[T]]
  tTag.newArray(length)
}
在答复中:

scala> makeArray[String](5)
res0: Array[String] = Array(null, null, null, null, null)
scala> val ai1 = Array[Int](1, 2, 3)
ai1: Array[Int] = Array(1, 2, 3)

scala> val as1 = Array[String]("one", "two", "three")
as1: Array[String] = Array(one, two, three)

scala> makeArrayLike(as1, 5)
res0: Array[_] = Array(null, null, null, null, null)

scala> makeArrayLike(ai1, 5)
res1: Array[_] = Array(0, 0, 0, 0, 0)
对于基本类型:

scala> makeArray[Int](5)
res1: Array[Int] = Array(0, 0, 0, 0, 0)
编辑:选择两个:

def makeArrayLike(a: Array[_], length: Int): Array[_] = {
  val cA = a.getClass
  val cC = cA.getComponentType
  java.lang.reflect.Array.newInstance(cC, length).asInstanceOf[Array[_]]
}
在答复中:

scala> makeArray[String](5)
res0: Array[String] = Array(null, null, null, null, null)
scala> val ai1 = Array[Int](1, 2, 3)
ai1: Array[Int] = Array(1, 2, 3)

scala> val as1 = Array[String]("one", "two", "three")
as1: Array[String] = Array(one, two, three)

scala> makeArrayLike(as1, 5)
res0: Array[_] = Array(null, null, null, null, null)

scala> makeArrayLike(ai1, 5)
res1: Array[_] = Array(0, 0, 0, 0, 0)

谢谢,但是与类型Array[Int]相同吗?因此类型应该是
Array[Int]
类似的:
makeArray[Array[Int]](5)
。我正在寻找一种方法来提取类型参数并将其转换为数组类型,就像上面的类型T一样。@JensEgholm:是的。基本类型也可以。我用一个示例编辑了我的答案。问题是我没有创建数组的对象类型。我知道类型是array[X],我需要提取X并生成给定类型的数组(为了完成上面的示例,这可能不是最好的方法)。然后我最好的建议是,对于您试图解决的任何问题,您都可以找到一个静态类型的解决方案。我添加了一个解决方案,但它是静态真空类型的…嗯..它几乎就在那里:-)我只是想知道:因为在运行时检索类型在技术上是可能的,所以应该可以创建具有该类型的类型化数组,对吗?