为了账号安全,请及时绑定邮箱和手机立即绑定

什么是Scala中的清单,什么时候需要它?

什么是Scala中的清单,什么时候需要它?

缥缈止盈 2019-09-19 10:42:14
从Scala 2.7.2开始,有一些叫做ManifestJava类型擦除的解决方法。但是,如何Manifest确切地工作以及为什么/何时需要使用它?Jorge Ortiz 的博客文章Manifests:Reified Types解释了其中的一些内容,但它没有解释如何将它与上下文界限一起使用。那么ClassManifest,有什么区别Manifest?我有一些代码(一个更大的程序的一部分,不能轻易地包含在这里),它有关于类型擦除的一些警告; 我怀疑我可以通过使用清单解决这些问题,但我不确定如何解决。
查看完整描述

3 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

不是一个完整的答案,但对于之间的区别Manifest和ClassManifest,你可以找到一个例子斯卡拉2.8 Array纸:


唯一剩下的问题是如何实现通用数组创建。与Java不同,Scala允许实例创建new  Array[T],其中T是类型参数。考虑到Java中不存在统一的数组表示,如何实现它?


执行此操作的唯一方法是需要额外的运行时信息来描述类型T。Scala 2.8有一个新的机制,称为Manifest。类型对象Manifest[T]提供有关类型的完整信息T。

Manifest值通常在隐式参数中传递; 并且编译器知道如何为静态已知类型构造它们T。


还存在一个较弱的命名形式ClassManifest,它可以通过只知道一个类型的顶级类来构造,而不必知道它的所有参数类型。

正是这种类型的运行时信息是数组创建所必需的。


例:


需要通过将ClassManifest[T]方法作为隐式参数传递给方法来提供此信息:


def  tabulate[T](len:Int,  f:Int=>T)(implicit m:ClassManifest[T]) =  { 

  val  xs  =  new  Array[T](len) 

  for   (i  <- 0  until   len)  xs(i)   = f(i) 

  xs 

作为简写形式,可以在类型参数上使用上下文bound1 T,


(见这个问题的插图)


给予:


def  tabulate[T:    ClassManifest](len:Int,  f:Int=>T)  =  { 

  val  xs  =  new  Array[T](len) 

  for   (i  <- 0  until   len)  xs(i)   = f(i) 

  xs 

当在类型上调用tabulate时Int,或者,或者String,或者List[T],Scala编译器可以创建一个类清单作为隐式参数传递给表格。


查看完整回答
反对 回复 2019-09-19
?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

Manifest旨在重新定义在JVM上运行类型擦除的泛型类型(不支持泛型)。然而,他们有一些严重的问题:他们太简单了,并且无法完全支持Scala的类型系统。因此它们在Scala 2.10中被弃用,并被替换为TypeTags(这实际上是Scala编译器本身用于表示类型的内容,因此完全支持Scala类型)。



查看完整回答
反对 回复 2019-09-19
  • 3 回答
  • 0 关注
  • 508 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信