標籤:

在 Scala 中實現泛型函數

我們知道,在 Scala 中方法是可以帶有泛型參數,而函數不行。那麼我們有沒有辦法讓函數模擬出泛型的效果呢?在 Scala 2 中,我們可以通過結構類型實現:

type T = { def apply[A](a: A): A }n

然後可以這樣使用:

val f: T = (identity[Any] _).asInstanceOf[T]n

試試效果:

scala> f(10)nres0: Int = 10nnscala> f("abc")nres1: String = abcn

我們甚至通過這個模擬一個帶有隱式參數的函數:

val f: {def apply[A : ClassTag](args: A*): Array[A]} = Arrayn

然後這樣使用:

scala> f(1, 2, 3)nres0: Array[Int] = Array(1, 2, 3)n

在 Dotty 里,這種做法已經不可行了,但是我們能夠用其他能力來在限定的情況下模擬出類似的效果:

scala> type T = (a: Any) => a.typen// defined alias type T = (a: Any) => a.typenscala> val f: T = identity.asInstanceOf[T]nval f: (a: Any) => a.type = Lambda$1433/1638796611@ef718denscala> f(10)nval res0: Int = 10n

註:res0 的實際類型本來應該是 『10』,不過單例類型在大多數場合都會提升為非單例類型。

不過雖然這樣做能在一定程度上實現泛型方法的效果,但是實際上受限程度還是很大。期待 Dotty 能引入 forall。


推薦閱讀:

Data class 是好東西,Kotlin 就差一個 pattern matching 了
#scala#模式匹配
【太閣x周刊】第十一期:紐約線下活動預告、技術討論群熱點話題、Scala中的Typeclass模式實例、人氣文章
提議:在Dotty 中使用縮進語法

TAG:Dotty | Scala |