scala:类型为

时间:2016-01-03 23:59:06

标签: scala

考虑以下类的定义。

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

有关如何使用类型标记为此类创建空构造函数的任何想法?

1 个答案:

答案 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)