2013-03-09 2 views
0

Я пытаюсь создать «реестр» объектов Companion - путем их хранения в списке, который связан с помощью Generics.Объект Companion в списке, связанный супер-признаком класса class

Пример лучше: сообщил

trait Foo 
case class A() extends Foo 
object A 
case class B() extends Foo 
object B 
case class C() extends Foo 
object C 


trait HasFoos { 
    def allFoos: List[ _ <: Foo.type] 
} 
case class FooLookup() extends HasFoos { 
    def allFoos = List(A,B,C) 
} 

Ошибка на FooLookup "Защиту allFoos" является

  • несоответствие типов; Найдено: A. необходимо: Foo.type

Необходимо, чтобы HasFoos.allFoos выглядел, или, альтернативно, должен выглядеть список (A, B, C).

Я попробовал def allFoos: List[ _ <: Foo]; однако это также ошибки, и я хочу работать с «Companion Object», а не классом - я уверен, что мне нужна еще более общая сахара-пыль вокруг него, но я не уверен, чего он требует.

благодарит заранее.

+2

Я хотел бы указать, что подстановочный знак здесь: 'def allFoos: List [_ <: Foo.type]' не нужно из-за дисперсии типа Scala. 'List' в scala является ковариантным, что означает, что вы можете безопасно присваивать тип, например,' List [String] 'переменной типа' List [Any] '- что-то, что вы никогда не могли бы сделать на Java. – ghik

ответ

4

Таким образом, как я уже писал, я не могу дойти до определения класса case FooLookup, потому что я получаю сообщение об ошибке «not found: значение Foo» в определении признака HasFoos.

Чтобы получить HasFoos для компиляции в письменном виде, вы должны в какой-то момент определить объект Foo, а также черту, нет? Если я это сделаю, HasFoos будет компилироваться. Но тогда «Foo.type» - это тип одиночного объекта Foo, а не тип сопутствующих объектов классов, которые расширяют черту Foo.

A.type будет типом объекта A. Это не будет тип вещей, реализующих признак компаньона A, если бы он был определен.

Я не думаю, что существует абстракция типа для чего вы хотите, что автоматически фиксирует описание «Объект Companion типа, который реализует Foo». Я думаю, что вы должны будете определить такой тип самостоятельно:

trait FooCompanion 
trait Foo 
case class A() extends Foo 
object A extends FooCompanion 
case class B() extends Foo 
object B extends FooCompanion 
case class C() extends Foo 
object C extends FooCompanion 

trait HasFoos { 
    def allFoos: List[FooCompanion] 
} 

case class FooLookup() extends HasFoos { 
    def allFoos = List(A,B,C) 
} 

Удачи вам!

+0

Вы определили мое «желание» succintly. ** «Объект компаньона типа, который реализует Foo.» **; поэтому добавление черты FooCompanion, безусловно, дает мне то, за чем я был. Спасибо .. (я думал об этом слишком сложно) – Ramon