2014-10-04 46 views
4

在处理一些Java代码时,我想找到一种方法来减少Raw Set以包含其参数化类型。我可以使用在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。

+1

我认为鉴于必然('<%')将从2.12弃用。就这样你知道 – 2014-10-05 04:18:33

回答

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 desugars实际的构造函数:

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

...(即取set在一个参数列表中并且在另一个中隐含evidence$1)。

如图值类限制here描述:

必须只有正好与一个公共的,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] 
          ^
4

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

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

desugars到

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

不再仅仅具有一个参数。

相关问题