在下面的代码中,为什么我可以返回Array[A]而不能返回A?如何返回A
scala> import scala.reflect._
import scala.reflect._
scala> class Covariant[+A]{
| def m[A:ClassTag]:Array[A] = new Array[A](1)
| }
defined class Covariant
scala> class Covariant[+A]{
| def m[A:ClassTag]:A = new A
| }
<console>:15: error: class type required but A found
def m[A:ClassTag]:A = new A
^发布于 2017-12-12 00:50:52
问题源于这样一个事实,即存在没有默认构造函数(即没有参数)的类。例如,您不能创建
case class IntWrapper(value:Int)而不提供一些Int值。此外,在Scala中没有办法表达类型必须具有这样的构造函数的约束。因此Scala编译器不能为new A生成任何有效的代码。它适用于数组,因为所有数组都具有相同的形状,即所有数组都有一个构造函数,其中恰好有一个Int参数,因此编译器可以在此处生成有效的调用。
也许你能有的最好的解决办法就是用默认构造函数为类型创建你自己的类型类:
trait DefaultConstructor[A] {
def create(): A
}
class Covariant[+A] {
def m[A](implicit ctr:DefaultConstructor[A]): A = ctr.create()
}发布于 2017-12-12 00:38:43
好吧..。答案很简单,在这两个示例中,您正在做不同的事情,
如果您尝试在Array示例中执行相同的操作,将会得到相同的错误。
scala> import scala.reflect._
// import scala.reflect._
scala> def m[A:ClassTag]:Array[A] = List(new A).toArray
// <console>:16: error: class type required but A found
// def m[A:ClassTag]:Array[A] = List(new A).toArray
// ^
scala> def m[A:ClassTag]:A = new A
// <console>:16: error: class type required but A found
// def m[A:ClassTag]:A = new A
// ^如果你想让它工作的话。您需要从TypeTag证据中获取构造函数,
import scala.reflect._
def createNewInstance[A: ClassTag] = {
val clazz = classOf[A]
val constructors = clazz.getConstructors
val defaultConstructor = constructors(0)
val instance = defaultConstructor.newInstance()
instance.asInstanceOf[A]
}
def m[A:ClassTag]: Array[A] = List(createNewInstance[A]).toArray
def m[A:ClassTag]: A = createNewInstance[A]发布于 2017-12-12 01:02:13
new关键字用于创建class的新实例。因为数组是一个有效的类,所以新的数组A是一个有效的语句。但是,新的A是无效的,因为A不是有效的类类型(错误已经指出)。因此出现了编译时错误。
我不确定您想要做什么,但是要返回类型A的结果,您可以简单地使用以下代码:
def m[A:ClassTag](a:A) = a https://stackoverflow.com/questions/47757222
复制相似问题