2014-10-04 2 views
4

Имея дело с некоторым кодом Java, я хотел найти способ уменьшить Raw Set, чтобы включить его параметризованный тип.Могу ли я использовать привязку вида в классе значений Scala?

Я также хотел, чтобы работать на 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 { 

Я Жду» t найти упоминание об этом типе ограничений в документах Scala View Bounds или Value Class.

Почему это запрещено? Я использую Scala 2.10.3.

+1

Я думаю, что вид связан ('<% ') будет отклоняться от 2.12. Просто чтобы вы знали –

ответ

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:

должен иметь только первичный конструктор с точно один общественности, параметр валь, тип которого не является классом значение.

... whitch означает, что Harden нарушает это ограничение.

Вы можете достичь чего-то подобного, howerver. Попытайтесь преобразовать свою привязку вида, определенную в классе, к неявным доказательствам метода.

Что-то вроде этого:

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) 

, который больше не имеет только один параметр.

Смежные вопросы