Отсутствует манифест класса для массива члена абстрактного типа - PullRequest
3 голосов
/ 13 ноября 2011

Я ищу рекомендации по предоставлению манифеста класса в экземпляре массива.Я реорганизовал этот код (который прекрасно компилируется):

trait Ref[A]
trait Struct[A] {
  val arr = new Array[Ref[A]](1)
}

к этому:

trait Ref[S <: Sys[S], A]
trait Sys[Self <: Sys[Self]] {
  type R[A] <: Ref[Self, A]
}

trait Struct[S <: Sys[S], A] {
  val arr = new Array[S#R[A]](1)
}

Это не с сообщением "cannot find class manifest for element type S#R[A]"

Так как бы я решилэто?

Ответы [ 2 ]

2 голосов
/ 13 ноября 2011

Ваша проблема в том, что Array, инвариантный в параметре типа, требует точного аргумента типа.Ваше определение type R в Sys предусматривает только верхнюю границу.

Вы можете устранить проблему на сайте определения, заменив верхнюю границу R равенством

* 1008.*

В качестве альтернативы, если вы предпочитаете оставить R[A] открытым в Sys, вы можете указать ограничение равенства на сайте использования с помощью уточнения, например, так:

trait Ref[S <: Sys[S], A]
trait Sys[Self <: Sys[Self]] {
  type R[A] <: Ref[Self, A]       // Back to an upper bound
}

trait Struct[S <: Sys[S] { type R[A] = Ref[S, A] }, A] {
//                       ^^^^^^^^^^^^^^^^^^^^^^^^^
//                       Assert the equality via a refinement
  val arr = new Array[S#R[A]](1)  // OK
}

Если вы можетеНе указывайте type R любым из этих способов, тогда у вас нет другого выбора, кроме как предоставить ClassManifest самостоятельно,

trait Ref[S <: Sys[S], A]
trait Sys[Self <: Sys[Self]] {
  type R[A] <: Ref[Self, A]
}

trait Struct[S <: Sys[S], A] {
  implicit val rM : ClassManifest[S#R[A]] // Provided manifest later ...
  val arr = new Array[S#R[A]](1)  // OK 
}

class SomeSys extends Sys[SomeSys] {
  type R[A] = Ref[SomeSys, A]
}

val s = new Struct[SomeSys, Int] {
  val rM = implicitly[ClassManifest[SomeSys#R[Int]]]
  //                                ^^^^^^^^^^^^^^
  //                                Precise type known here
}

Какой из них выбрать, очень сильно зависит от вашего более широкого контекста.

2 голосов
/ 13 ноября 2011

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

trait Sys[Self <: Sys[Self]] {
  type R[A] <: Ref[Self, A]
  def newRefArray[A](size: Int): Array[Self#R[A]]
}

trait Struct[S <: Sys[S], A] {
  def sys: S
  val arr = sys.newRefArray[A](1)
}
...