从 Scala 2.7.2 开始,有一个名为 Manifest
的东西,它是 Java 类型擦除的解决方法。但是 Manifest
到底是如何工作的以及为什么/何时需要使用它?
博客文章清单:具体化类型< Jorge Ortiz 的 /em> 解释了其中的一些内容,但没有解释如何将其与 上下文边界。
另外,ClassManifest
是什么,和Manifest
有什么区别?
我有一些代码(较大程序的一部分,不能轻易地将其包含在此处),其中有一些关于类型擦除的警告;我怀疑我可以通过使用清单来解决这些问题,但我不确定具体如何解决。
Since Scala 2.7.2 there is something called Manifest
which is a workaround for Java's type erasure. But how does Manifest
work exactly and why / when do you need to use it?
The blog post Manifests: Reified Types by Jorge Ortiz explains some of it, but it doesn't explain how to use it together with context bounds.
Also, what is ClassManifest
, what's the difference with Manifest
?
I have some code (part of a larger program, can't easily include it here) that has some warnings with regard to type erasure; I suspect I can solve these by using manifests, but I'm not sure exactly how.
发布评论
评论(4)
编译器知道的有关类型的信息比 JVM 运行时可以轻松表示的更多。清单是编译器在运行时向代码发送有关丢失的类型信息的跨维度消息的一种方式。
在不了解更多细节的情况下,尚不清楚清单是否有利于您所看到的错误。
清单的一种常见用途是让代码根据集合的静态类型表现不同。例如,如果您想将 List[String] 与其他类型的列表区别对待,该怎么办:
基于反射的解决方案可能会涉及检查列表的每个元素。
上下文绑定似乎最适合在 scala 中使用类型类,Debasish Ghosh 在这里很好地解释了这一点:
http://debasishg.blogspot.com/ 2010/06/scala-implicits-type-classes-here-i.html
上下文边界还可以使方法签名更具可读性。例如,上面的函数可以使用上下文边界重写,如下所示:
The compiler knows more information about types than the JVM runtime can easily represent. A Manifest is a way for the compiler to send an inter-dimensional message to the code at runtime about the type information that was lost.
It isn't clear if a Manifest would benefit the errors you are seeing without knowing more detail.
One common use of Manifests is to have your code behave differently based on the static type of a collection. For example, what if you wanted to treat a List[String] differently from other types of a List:
A reflection-based solution to this would probably involve inspecting each element of the list.
A context bound seems most suited to using type-classes in scala, and is well explained here by Debasish Ghosh:
http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html
Context bounds can also just make the method signatures more readable. For example, the above function could be re-written using context bounds like so:
清单旨在具体化经过类型擦除以在 JVM 上运行的泛型类型(JVM 不支持泛型)。然而,它们有一些严重的问题:它们过于简单化,并且无法完全支持 Scala 的类型系统。因此,它们在 Scala 2.10 中被弃用,并被
TypeTag
取代(这本质上是 Scala 编译器本身用来表示类型的内容,因此完全支持 Scala 类型)。有关差异的更多详细信息,请参阅:换句话说
2013 年 1 月 4 日之前,Scala 2.10 发布时。
A Manifest was intended to reify generic types that get type-erased to run on the JVM (which does not support generics). However, they had some serious issues: they were too simplistic, and were unable to fully support Scala's type system. They were thus deprecated in Scala 2.10, and are replaced with
TypeTag
s (which are essentially what the Scala compiler itself uses to represent types, and therefore fully support Scala types). For more details on the difference, see:In other words
Before 2013-01-04, when Scala 2.10 was released.
这不是一个完整的答案,但关于
Manifest
和ClassManifest
之间的区别,您可以在 Scala 2.8Array
论文:例子:
(参见此SO 问题用于说明)
Not a complete answer, but regarding the difference between
Manifest
andClassManifest
, you can find an example in the Scala 2.8Array
paper:Example:
(See this SO question for illustration)
我们还检查
scala
源 (Manifest.scala
) 中的manifest
,我们看到:因此,对于以下示例代码:
我们可以看到
manifest
function
搜索隐式m:Manifest[T]
,它满足您在我们的代码中提供的类型参数
示例代码是manifest[String]
。因此,当您调用类似以下内容时:您正在检查您在函数中定义的当前
隐式 m
是否为manifest[String]
类型,并且作为manifest< /code> 是一个
manifest[T]
类型的函数,它将搜索特定的manifest[String]
并查找是否存在这样的隐式。Let's also chck out
manifest
inscala
sources (Manifest.scala
), we see:So with regards to following example code:
we can see that the
manifest
function
searches for an implicitm: Manifest[T]
which satisfies thetype parameter
you provide in our example code it wasmanifest[String]
. So when you call something like:you are checking if the current
implicit m
which you defined in your function is of typemanifest[String]
and as themanifest
is a function of typemanifest[T]
it would search for a specificmanifest[String]
and it would find if there is such an implicit.