2016-08-31 147 views
2

我想要一個具有靜態可用的函數的類(它由一個特徵收縮)。然後我想要一個類型參數化的方法,它接受這樣的類型作爲它的類型參數,並訪問合同化的靜態函數。 (是的,我知道術語static是Java而不是Scala,但你知道我的意思。)伴侶類型的Scala類型約束

我知道在Scala中有一個靜態函數的唯一方法是讓伴隨對象擴展特徵。然而,這樣做有兩個問題:

  1. 我不知道如何約束類型參數,使它的伴侶對象擴展了一些特質。
  2. 我不知道我將如何訪問靜態方法,該類實際上是與其伴侶對象不同的類型。

這可能是完全關閉,但有點是我想要做的是:

MyTrait { 
    def MyFunction() : Any //some function 
} 

case class MyClass(i: Int) 

object MyClass extends MyTrait { 
    def MyFunction() = {/*do stuff*/} 
} 

//need the type as a class not an object because I need it for a higher order function like this 
def SomeFunctionHigherOrderFunction[T /*constrain T such that the companion object of T <: MyTrait*/](someFunc : Function1[T, Any]) : Unit { 
    val someStuff = T.MyFunction() 
    /*use someStuff in here*/ 
} 

SomeFunctionHigherOrderFunction[T](/*provide a Function1[T, Any]*/); 

正確的解決方案的任何想法或要對這個問題的一些更好的方法?

在此先感謝!

+1

你必須使用它你的代碼中有些拼寫錯誤。 [確保我們可以編譯你給我們的例子!](http://sscce.org/) –

回答

0

沒有辦法做到這一點。你可以採取的一種方法是通過implicits傳遞方法(這也被稱爲類型類方法)。你需要通過T參數化你的特質(即使你不使用它,T被用來解決右邊的隱含問題)。

trait MyTrait[T] { 
    def MyFunction() : Any //some function (usually you want to use `T` somehow) 
} 

然後,您聲明伴隨對象是隱式的。事情是這樣的

implicit object MyClass extends MyTrait[MyClass] { 
    def MyFunction = ... 
} 

或者,如果你沒有什麼該對象一樣,你甚至可以這樣做只是在線:

implicit val myTraitMyClass: MyTrait[MyClass] = new MyTrait[MyClass] { 
    def MyFunction = ... 
} 

,並通過

def SomeHigherOrderFunction[T](someFunc : Function1[T, Any])(implicit o: MyTrait[T]): Unit { 
    val someStuff = o.MyFunction() 
    /*use someStuff in here*/ 
} 
+0

這個解決方案非常棒!唯一的問題是'隱式對象MyClass'不能被定義爲頂級實體,這是令人討厭的,因爲我現在需要將對象嵌套在另一個類中,並且有一個額外的導入(除非我也嵌套了類有點尷尬)。感謝@Alec分享。 – Danny