2010-04-07 93 views
8

在斯卡拉v 2.7.7斯卡拉傳遞類型參數爲對象

我有

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同伴對象。

但是,我的建議是不要開始擺弄設計一般API(尤其是自我指涉的像上面的),除非你真的,真的知道你在做什麼。幾乎可以肯定將結束在流淚,並有大量的核心Java API的,因爲這樣的仿製藥已添加的這是可怕的(上JTableRowSorter API就是一個例子)

+0

APT的API也不錯:'名單<?擴展AnnotationMirror> \t getAnnotationMirrors()'(http://java.sun.com/javase/6/docs/api/javax/lang/model/element/Element.html#getAnnotationMirrors%28%29);-) – 2010-04-07 15:32: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 
} 

注意這將重新構建富[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 
}