2014-10-04 72 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) 

不再僅僅具有一個參數。

相關問題