我可以在Scala值类中使用绑定的视图吗?

时间:2014-10-04 20:25:24

标签: scala generics

在处理一些Java代码时,我想找到一种方法来减少原始集以包含其参数化类型。

我也希望它也适用于Scala集,所以我做了以下

implicit class Harden[S <% mutable.Set[_]](val set: S) extends AnyVal {
    def cast[T] = set.map(_.asInstanceOf[T])
}

这导致编译器错误,我没想到

Error:(27, 27) field definition is not allowed in value class
  implicit class Harden[S <% mutable.Set[_]](val set: S) extends AnyVal {

我在Scala View Bounds或Value Class文档中没有发现任何类型的限制。

为什么不允许这样做?我使用的是Scala 2.10.3。

2 个答案:

答案 0 :(得分:5)

从这个 sbt控制台输出中可以看到:

scala> :type implicit class Harden[S <% mutable.Set[_]](val set: S)
[S]AnyRef {
  val set: S
  private[this] val set: S
  implicit private[this] val evidence$1: S => scala.collection.mutable.Set[_]
  def <init>(set: S)(implicit evidence$1: S => scala.collection.mutable.Set[_]): Harden[S]
}

...... Harden的实际构造函数在幕后躲避:

def <init>(set: S)(implicit evidence$1: S => scala.collection.mutable.Set[_]): Harden[S]

...(即在一个参数列表中取set而在另一个参数列表中取隐式evidence$1

如价值类限制here中所述:

  

必须只有一个主构造函数,其中只有一个public,val参数,其类型不是值类。

... whitch表示Harden违反了此限制。

你可以达到类似的目标。尝试将类上定义的视图绑定转换为方法上的隐式证据。

这样的事情:

scala> implicit class Harden[S](val set: S) extends AnyVal {
     |     def cast[T](implicit ev: S => scala.collection.mutable.Set[_]) = set.map(_.asInstanceOf[T])
     | }
defined class Harden

这将编译:

scala> Set(1,2,3).cast[Any]
res17: scala.collection.mutable.Set[Any] = Set(1, 2, 3)

这将失败,正如所料:

scala> List(1,2,3).cast[Any]
<console>:24: error: No implicit view available from List[Int] => scala.collection.mutable.Set[_].
              List(1,2,3).cast[Any]
                              ^

答案 1 :(得分:4)

这是不允许的,因为现在结构化,值类必须只有一个参数,但

implicit class Foo[A <% B](val a: A)

desugars to

implicit class Foo[A,B](val a: A)(implicit evidence$1: A => B)

不再只有一个参数。