2016-05-17 2 views
0

В абстрактном классе scala, если вы хотите определить привязку к контексту, вы можете просто использовать, например. [T: ClassTag] в параметре, однако это не представляется возможным в черте:Сокращение для определения контекста scala, связанного в признаке

trait Foo[T: ClassTag] 

Error:(11, 35) traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...' 
trait Foo[T: ClassTag] 
     ^

если вы определяете:

trait Foo[T] { 

    implicit def ctg: ClassTag[T] = implicitly[ClassTag[T]] 
} 

object Bar extends Foo[Int] 

тогда любая попытка чтения КТГ в баре вызовет StackOverflowError, как неявное параметр становится рекурсивным.

Итак, каков наилучший способ определения ctg в признаке, который автоматически выставляет подклассы привязки к контексту?

ответ

2

Неприятный способ. Ограничение контекста является кратким для неявного параметра, а черты не имеют параметров. То есть, когда вы пишете:

class Foo[T : ClasTag] 

Компилятор де-сахарами ваш код:

class Foo[T](implicit ev: ClassTag[T]) 

Это, конечно, не представляется возможным с признаком. Если вы должны Обойти это с чертой, вы можете сделать ClassTag абстрактные и заставить класс, который расширяет его реализовать:

trait Foo[T] { 
    implicit def ctg: ClassTag[T] 
} 

object Bar extends Foo[Int] { 
    implicit val ctg = classTag[Int] 
} 

Это выглядит немного лучше с классом в середине, так что вам не нужно указывать Int дважды при определении Bar:

trait Foo[T] { 
    implicit def ctg: ClassTag[T] 
} 

class FooImpl[T](implicit val ctg: ClassTag[T]) extends Foo[T] 

object Bar extends FooImpl[Int] 
+0

Спасибо. Печально знать, что это не поддерживается, надеюсь, что автоматическое обезжиривание может стать особенностью в будущем – tribbloid

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