简体   繁体   English

scala:具有类型标签的类的空构造函数

[英]scala: empty constructor for a class with type tag

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? 有什么想法如何使用类型标记为此类创建一个空的构造函数?

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. 您将主构造函数视为具有签名(String, T => String, Option[List[String]]) ,但这并不完全正确。 In fact, it's (String, T => String, Option[List[String]])(ClassTag[T]) (note the ClassTag parameter). 实际上,它是(String, T => String, Option[List[String]])(ClassTag[T]) (请注意ClassTag参数)。

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. 但是,ClassTag有点特殊-在编译时会使用与您的T对应的ClassTag进行填充。 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. 每个辅助构造函数中的问题是T仍然是通用的,因此编译器不知道要包含哪个ClassTag:在该范围内没有隐式参数可用。

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; 请注意,您无需向链式构造函数明确证明ClassTag 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM