考虑以下类的定义。
case class DiscreteProperty[T <: AnyRef](
name: String,
sensor: T => String,
range: Option[List[String]]
)(implicit val tag: ClassTag[T]) extends TypedProperty[T, String] {
/// some stuff here
}
我在某些时候收到以下错误:
Can't instantiate 'edu.illinois.cs.cogcomp.saul.datamodel.property.features.discrete.DiscreteProperty$$anon$2':
我想这是因为该类没有空构造函数。如何为此类定义空构造函数?我尝试了以下但它给了我以下错误:
def this() {
this("funnyName", T => "" ,Option(List()))
}
这些都不起作用:
def this[T]() {
this("funnyName", T => "" ,Option(List()))
}
或
def this[T]() {
this[T]("funnyName", T => "" ,Option(List()))
}
有关如何使用类型标记为此类创建空构造函数的任何想法?
答案 0 :(得分:3)
问题是您没有在任何空构造函数中包含隐式参数。您将主要构造函数视为具有签名(String, T => String, Option[List[String]])
,但这并不完全正确。事实上,它是(String, T => String, Option[List[String]])(ClassTag[T])
(请注意ClassTag
参数)。
通常这不是问题,因为隐式参数将从该构造函数的范围中检索。但是,ClassTag有点特殊 - 它在编译时填充,ClassTag对应于T
。每个辅助构造函数中的问题是T
仍然是通用的,因此编译器不知道要包含哪个ClassTag:在该范围内没有可用的隐式参数。
那么,你怎么解决它?最简单的方法可能是在任何辅助构造函数中包含隐式参数:
def this()(implicit tag: ClassTag[T]) = this("funnyName", T => "", Option(List()))
请注意,您不需要向链式构造函数明确证明ClassTag
;它现在是范围的一部分,将被隐式使用。当然,您可以明确地决定这样做:
def this()(implicit tag: ClassTag[T]) = this("funnyName", T => "", Option(List()))(tag)