Почему Манифест недоступен в конструкторе?
Рассмотрим этот код:
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)
}
1 ответ
Когда синтаксический сахар удаляется из этого контекста, он переписывается как:
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)
}
Так что да, манифест доступен до вызова manifest[T].erasure