首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我可以使用Classtag返回Array[A]而不能返回A?如何返回A?

为什么我可以使用Classtag返回Array[A]而不能返回A?如何返回A?
EN

Stack Overflow用户
提问于 2017-12-12 00:28:12
回答 3查看 79关注 0票数 0

在下面的代码中,为什么我可以返回Array[A]而不能返回A?如何返回A

代码语言:javascript
复制
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
                                 ^
EN

回答 3

Stack Overflow用户

发布于 2017-12-12 00:50:52

问题源于这样一个事实,即存在没有默认构造函数(即没有参数)的类。例如,您不能创建

代码语言:javascript
复制
case class IntWrapper(value:Int)

而不提供一些Int值。此外,在Scala中没有办法表达类型必须具有这样的构造函数的约束。因此Scala编译器不能为new A生成任何有效的代码。它适用于数组,因为所有数组都具有相同的形状,即所有数组都有一个构造函数,其中恰好有一个Int参数,因此编译器可以在此处生成有效的调用。

也许你能有的最好的解决办法就是用默认构造函数为类型创建你自己的类型类:

代码语言:javascript
复制
trait DefaultConstructor[A] {
  def create(): A
}

class Covariant[+A] {
  def m[A](implicit ctr:DefaultConstructor[A]): A = ctr.create()
}
票数 2
EN

Stack Overflow用户

发布于 2017-12-12 00:38:43

好吧..。答案很简单,在这两个示例中,您正在做不同的事情,

如果您尝试在Array示例中执行相同的操作,将会得到相同的错误。

代码语言:javascript
复制
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证据中获取构造函数,

代码语言:javascript
复制
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]
票数 0
EN

Stack Overflow用户

发布于 2017-12-12 01:02:13

new关键字用于创建class的新实例。因为数组是一个有效的类,所以新的数组A是一个有效的语句。但是,新的A是无效的,因为A不是有效的类类型(错误已经指出)。因此出现了编译时错误。

我不确定您想要做什么,但是要返回类型A的结果,您可以简单地使用以下代码:

代码语言:javascript
复制
def m[A:ClassTag](a:A) = a 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47757222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档