【问题标题】:Can I construct a ClassManifest for a parameterized type without having manifests for the type parameters?我可以在没有类型参数清单的情况下为参数化类型构造 ClassManifest 吗?
【发布时间】:2012-06-28 23:53:49
【问题描述】:

ClassManifest[T] 在 Scala 中主要用于创建 Array[T]。

我对数组类型 T 不是原始类型而是某个采用类型构造函数的类(即 AnyRef 的子类型)的情况感兴趣。然后,我可以为参数化类型构造一个 ClassManifest,而不需要其类型参数的清单吗?

class Foo[A]

def getManifestFor[A]: ClassManifest[Foo[A]] = ???

由于 Foo 是非原始的,看来 JVM 数组存储将是一个引用数组,其大小/内存布局不受擦除类型参数的影响(例如上面的 A)。所以理论上似乎可行,但我不知道如何用Scala编写。

【问题讨论】:

  • 一些实验回答了我的问题:def manifestFor[A]: ClassManifest[Foo[A]] = implicitly[ClassManifest[Foo[A]]]implicitly 搜索隐式 ClassManifest[Foo[A]]。由于我上面提到的原因,我想编译器可以提供一个。现在回想起来,这似乎很明显。我最初感到困惑,因为在我的应用程序中我对类型粗心,并且使用了 Manifest[T],而不是 ClassManifest[T]。 Manifest[T] 意味着更高的准确性;类型 T 的所有部分都必须是已知的。即这是一个编译错误:def manifestFor[A]: Manifest[Foo[A]] = implicitly[Manifest[Foo[A]]]
  • 为什么隐式解决方案不合适?

标签: scala


【解决方案1】:

您的评论是正确的,正如您强调的那样,ClassManifest 比 Manifest 更“轻”,您可以从类型构造函数构建它。

scala> class Foo[A] 
defined class Foo

scala>  object test { def getManifestFor[A] = implicitly[ClassManifest[Foo[A]]] } 
defined module test

scala>  test.getManifestFor[Foo[Int]]
res2: ClassManifest[Foo[Foo[Int]]] = Foo[<?>]

scala>  :javap -p test
Compiled from "<console>"
public final class test$ extends java.lang.Object implements scala.ScalaObject{
    public static final test$ MODULE$;
    public static {};
    public scala.reflect.ClassManifest getManifestFor();
    public test$();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 2022-11-05
    • 2016-06-05
    相关资源
    最近更新 更多