为什么 Manifest 在构造函数中不可用?

发布于 2024-12-02 23:10:14 字数 452 浏览 6 评论 0原文

考虑这段代码:

class Foo[T : Manifest](val id: String = manifest[T].erasure.getName)

我基本上想在 Foo 中存储一个标识符,它通常只是类名。

不需要特殊标识符的子类可以轻松使用默认值。

但这甚至无法编译,错误消息是:

error: No Manifest available for T.

是否还有另一种可行的方法?

编辑:

如果清单在主构造函数之前不可用,为什么这会起作用?

class Foo[T: Manifest](val name: String) { 
  def this() = this(manifest[T].erasure.getName)
}

Consider this code:

class Foo[T : Manifest](val id: String = manifest[T].erasure.getName)

I basically want to store an identifier in Foo, which is often just the class name.

Subclass which do not need a special identifier could then easily use the default value.

But this doesn't even compile, the error message is:

error: No Manifest available for T.

Is there another approach which will work?

EDIT:

Why does this work if the manifest isn't available until the primary constructor?

class Foo[T: Manifest](val name: String) { 
  def this() = this(manifest[T].erasure.getName)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉态萌生 2024-12-09 23:10:14

当从该上下文绑定中删除语法糖时,它会被重写为:

class Foo[T]
  (val id: String = implicitly[Manifest[T]].erasure.getName)
  (implicit ev$1: Manifest[T]) = ...

因此,在确定 id 的默认值时,清单证据根本不可用。相反,我会写这样的内容:

class Foo[T : Manifest](id0: String = "") {
  val id = if (id0 != "") id0 else manifest[T].erasure.getName
}

在第二种方法中(顺便说一下,这是一个很好的解决方案!),期望重写类似于:

class Foo[T](val name: String)(implicit x$1: Manifest[T]) { 
  def this()(implicit ev$2: Manifest[T]) = this(manifest[T].erasure.getName)
}

所以是的,清单调用之前可用清单[T].擦除

When the syntactic sugar is removed from that context bound, it gets rewritten as:

class Foo[T]
  (val id: String = implicitly[Manifest[T]].erasure.getName)
  (implicit ev$1: Manifest[T]) = ...

So the Manifest evidence simply isn't available when determining the default value of id. I'd instead write something like this:

class Foo[T : Manifest](id0: String = "") {
  val id = if (id0 != "") id0 else manifest[T].erasure.getName
}

In your second approach (which is a great solution, by the way!), expect a rewrite similar to:

class Foo[T](val name: String)(implicit x$1: Manifest[T]) { 
  def this()(implicit ev$2: Manifest[T]) = this(manifest[T].erasure.getName)
}

So yes, the manifest is available before the call to manifest[T].erasure

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文