Why is the Manifest not available in the constructor?

偶尔善良 提交于 2019-12-01 15:32:52

问题


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)
}

回答1:


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



来源:https://stackoverflow.com/questions/7294761/why-is-the-manifest-not-available-in-the-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!