2012-07-27 28 views

回答

14

不是直接;在Scala中這樣做的通常方式是使用類型類。

trait FAble[T] { def doF: String } 
object FAble { 
    implicit val fInt = new FAble[Int] { def doF = "I'm an int" } 
    implicit val fFloat = new FAble[Float] { def doF = "I'm a float" } 
    implicit val fBurger = new FAble[Burger] { def doF = "You want fries?" } 
} 

def f[T](implicit ev: FAble[T]) = ev.doF 
// or 
def f[T: FAble] = implicitly[FAble[T]].doF 

這是更詳細的公平一點,但它具有一定的優勢太 - 隱含的實例可以(使用implicit def!而非val S)來計算,並且有可以爲任何給定類型不止一個實例,它允許您通過在代碼的不同位置範圍內有不同的實例來選擇行爲。

你不能使用C++方式的原因是Scala泛型不涉及不同類型參數的代碼生成(因爲它沒有做你想做的事情,所以不要使用@specialized)。所以說「嘿,編譯器,當你在該位置看到一個Int,而不是從通用模板生成代碼,而是使用這個特定的代碼」是沒有意義的。

1

您可能想要查看宏:http://scalamacros.org/。宏是在編譯期間運行的自定義函數,並且可以基於編譯時計算動態生成代碼。

2

另一種可能的方法是使用證據:

def f[T](t:T)(implicit ev: T<:<Float) { 

// float version 

} 

def f[T](t:T)(implicit ev: T<:<Int) { 

// int version 

} 

不過,我會建議型類作爲一個更優雅的解決方案

相關問題