2014-10-09 4 views
1

я хав ошибкой компиляции при использовании манифеста с абстрактным типом:Как использовать манифест с абстрактным типом

[error] No Manifest available for C#MV#A. 
[error]  def readGenSingle4[C <: MultiItemValue](h: Seq[C#MV] => C, json: JValue, g: (C#MV#A, Seq[Criteria.MatchCriteria]) => C#MV, f: JValue => C#MV#A = {v: JValue => v.extract[C#MV#A]})(implicit m: Manifest[C#MV#A]) = 

Есть ли способ исправить это?

ответ

0

Манифест устарел - вместо этого используйте ClassTag/TypeTag. Вы на самом деле не нужно, чтобы захватить ClassTag/TypeTag внутри вашей функции - вы можете сделать это в вашем классе (это единственный путь, потому что только класс может захватить его абстрактный тип во время выполнения):

trait MV{type A; implicit val t: TypeTag[A]} 

class MVString(implicit val t: TypeTag[String]) extends MV {type A = String} 

После этого - вы может получить доступ к TypeTag в качестве члена (new MVString).t - даже внутри вашей функции. Единственная проблема заключается в том, что вы должны явно указывать typeTag для каждой реализации. Возможное решение - использовать дженерики в сочетании с абстрактными типами:

abstract class MV[T](implicit val t: TypeTag[T]){type A = T} 

class MVString extends MV[String] 

scala> def readGenSingle4[C <: MV[T], T](a: C, b: C#A) = a.t 
readGenSingle4: [C <: MV[T], T](a: C, b: T)reflect.runtime.universe.TypeTag[T] 

scala> readGenSingle4(new MVString, "aaaa") 
res4: reflect.runtime.universe.TypeTag[String] = TypeTag[String]