3

Scala 2.10 增加了对值类的支持。值类的限制之一是它“必须只有一个主构造函数,其中只有一个公共的 val 参数,其类型不是值类。”

对单个 val 参数使用元组有什么缺点吗?

例如,我想创建一个值类型来表示具有开始和结束的时间段。因为我不能有两个参数,所以我可以将该范围表示为(Long, Long).

case class Period(timeRange: (Long, Long)) extends AnyVal {
  def start: Long = timeRange._1
  def end: Long = timeRange._2
  def contains(time: Long): Boolean = time >= start && time < end
}

使用这种方法,我还能获得值类的内存分配优势吗?

4

1 回答 1

3

正如您所说,缺点是您将创建一个额外的Tuple2对象来存储两个Longs。然而,不会有拳击——Tuple2专门用于Long. 所以——你最好在这种情况下创建一个案例类。

以下内容与您的问题没有直接关系,但可能有用。在某些情况下,如果您的值类是通用的,则您需要一个类型类。例如,假设您想!Numeric类型添加额外的阶乘方法。您必须执行以下操作:

implicit class IntegralOps[T: Numeric](val x: T) extends AnyVal {
  def ! = ???
}

这是行不通的,因为 typeclass 约束被转换为一个额外的隐式参数,而值类只支持一个参数:

implicit class IntegralOps[T](val x: T)(implicit $evidence: Numeric[T]) extends AnyVal {
  def ! = ???
}

在这种情况下,您可以避免的技巧是将 typeclass 参数移动到所有扩展方法:

implicit class IntegralOps[T](val x: T) extends AnyVal {
  def !(implicit $evidence: Numeric[T]) = ???
}

由于对IntegralOps类的隐式转换和对扩展方法的调用相同的调用点相同,因此相同的类型类将适用于两种情况。

于 2013-03-14T12:02:03.667 回答