2010-04-07 6 views
8

В Scala V 2.7.7параметры прохождения типа Scala объекта

У меня есть файл с

class Something[T] extends Other 

object Something extends OtherConstructor[Something] 

это бросает ошибку:

class Something takes type parameters
object Something extends OtherConstructor[Something] {

Однако, я не могу сделать это

object Something[T] extends OtherConstructor[Something[T]] 

Он выдает ошибку:

error: ';' expected but '[' found.

Можно ли отправить параметры типа объекту? Или я должен изменить и просто использовать Otherconstructor

ответ

3

Объект должен иметь конкретный тип. Контракт объекта Scala не является исключением из этого правила.

Действительное определение

object Something extends OtherConstructor[Something[T]] { } 

где T некоторые конкретный тип.

4

Вы могли бы использовать:

object Something extends OtherConstructor[Something[_]] 

Вы, конечно, будет ограничено, имея экзистенциальный тип с верхней границей не в месте, а не конкретного типа. Это решение может не иметь смысла, и вам может понадобиться один объект для конкретного типа T, для тех T, о которых вы заботитесь, например.

object StringSomething extends OtherConstructor[Something[String]] 

Но тогда это имеет (возможно) недостаток, что StringSomething не компаньоном объектом Something.

Однако, мой совет будет не начинает баловаться о разработке родового Apis (особенно самосправочных из них, как выше), если вы действительно, действительно не знаете, что вы делаете. Это почти наверняка закончится в слезах, и есть много CORE Java API, которые ужасны из-за добавленных в пути дженериков (RowSorter API на JTable является одним из примеров)

+0

меткому API хорош также: 'List \t getAnnotationMirrors() '(http://java.sun.com/javase/6/docs/api/javax/lang/model/element/Element.html#getAnnotationMirrors%28%29) ;-) –

1

Спасибо за ответы

object Something extends OtherConstructor[Something[_]] 

, кажется, компиляции (хотя я до сих пор запустить/проверить это :-))

@oxbow_lakes, я последовал вашему совету - избежать типа системы - до сих пор, но я должен это сделать !!! Я изучаю экзистенциальные типы, тип-стирание и все, что, но его до сих пор не в моих руках :-(

1

Вы можете решить общую проблему необходимости object Foo[T], перемещая параметр типа к методам в object Foo:

class Foo[T](t1: T, t2: T) 

object Foo { 
    def apply[T](x: T): Foo[T] = new Foo(x, x) 
    def apply[T](x: T, y: T): Foo[T] = new Foo(x, y) 
} 

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

class Foo[T](t1: T, t2: T) 

class FooCompanion[T] { 
    def apply(x: T): Foo[T] = new Foo(x, x) 
    def apply(x: T, y: T): Foo[T] = new Foo(x, y) 
} 

object Foo { 
    def apply[T] = new FooCompanion[T] 
} 

object demo extends App { 
    val x: Foo[Double] = Foo.apply.apply(1.23) // this is what is really happening 
    val y: Foo[Int] = Foo[Int](123)    // with the type both apply calls are automatic 
} 

Примечание это будет заново построить Foo [T ] компаньон на каждом звонке, чтобы вы хотели держать его светлым и безгосударственным.

Явное Решение проблемы выше:

class Other 

class OtherConstructor[O <: Other] { 
    def apply(o: O): O = o // constructor 1 in base class 
} 

class Something[T](value: T) extends Other 

class SomethingConstructor[T] extends OtherConstructor[Something[T]] { 
    def apply(o: T, s: String) = new Something[T](o) // constructor 2 in subclass 
} 

object Something { 
    def apply[T] = new SomethingConstructor[T] // the "constructor constructor" method 
} 

object demoX extends App { 
    val si = new Something(123) 
    val sd = new Something(1.23) 

    val si1: Something[Int] = Something[Int](si)     // OtherConstructor.apply 
    val sd1: Something[Double] = Something[Double](1.23, "hello") // SomethingConstructor[Double].apply 
} 
Смежные вопросы