Reputation: 6039
Consider the following definition for a class.
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
}
I am getting the following error at some point:
Can't instantiate 'edu.illinois.cs.cogcomp.saul.datamodel.property.features.discrete.DiscreteProperty$$anon$2':
I suppose this is because the class doesn't have an empty constructor. How can I define an empty constructor for this class? I tried the following but it is giving me the following error:
def this() {
this("funnyName", T => "" ,Option(List()))
}
And none of these work:
def this[T]() {
this("funnyName", T => "" ,Option(List()))
}
or
def this[T]() {
this[T]("funnyName", T => "" ,Option(List()))
}
Any ideas how to create an empty constructor for this class with type tag?
Upvotes: 0
Views: 657
Reputation: 1649
The issue is that you're not including the implicit parameter in any of your empty constructors. You're treating the primary constructor as having the signature (String, T => String, Option[List[String]])
, but that's not quite right. In fact, it's (String, T => String, Option[List[String]])(ClassTag[T])
(note the ClassTag
parameter).
Normally this wouldn't be an issue, since the implicit parameter would be retrieved from the scope of that constructor. However, ClassTag is a bit special - it is filled in at compile time with the ClassTag corresponding to whatever your T
is. The problem in each of those auxiliary constructors is that the T
is still generic, so the compiler doesn't know which ClassTag to include: there's no implicit parameter available within that scope.
So, how can you fix it? The easiest way is probably to include the implicit parameter in any auxiliary constructors:
def this()(implicit tag: ClassTag[T]) = this("funnyName", T => "", Option(List()))
Note that, you don't need to explicitly proved the ClassTag
to the chained constructor; it's now part of the scope and will be used implicitly. Of course, you can decide to do so explicitly like so:
def this()(implicit tag: ClassTag[T]) = this("funnyName", T => "", Option(List()))(tag)
Upvotes: 3