problem
在 scala 中,type parameter 可以為 primitive type,比如Int
, Long
, Float
, Double
...
但由于 JVM 的類型擦除僵闯,List[Int]
在運(yùn)行時仍會被轉(zhuǎn)化為List[Object]
即基礎(chǔ)類型需要被裝箱到某個wrapper class
中
@specialized
可以在聲明type parameter時,針對一些 type 使用@specialized
annotation
import scala.{specialized => sp}
class Wrapper[@sp(Short, Int, Long, Float, Double) A](unwrap: A)
new Wrapper[Short](42)
res0: Wrapper[Short] = Wrapper$mcS$sp@2f657dc7
new Wrapper[Int](42)
res1: Wrapper[Int] = Wrapper$mcI$sp@213b4ebf
new Wrapper[Long](42L)
res2: Wrapper[Long] = Wrapper$mcJ$sp@600f799c
new Wrapper[Float](3.14f)
res3: Wrapper[Float] = Wrapper$mcF$sp@5b6b6cb0
new Wrapper[Double](3.14)
res4: Wrapper[Double] = Wrapper$mcD$sp@465ebfb9
new Wrapper[String]("hi")
res5: Wrapper[String] = Wrapper@7ee6425d
可以看到,編譯器會針對所聲明的5個基礎(chǔ)類型和1個泛型捡絮,編譯出6個不同版本的Wrapper
.
這樣,對于specialized
的類型莲镣,就可以避免運(yùn)行時boxing
和unboxing
開銷福稳。
syntax
-
class
的 specialization 會應(yīng)用于所有使用了其 type parameter 的 members - 可以針對
class
和member
分別設(shè)置spacialization
// class Vector specialized all primitive types
class Vector[@specialized A] {
def apply(i: Int): A = //..
// method map only specialized Int and Boolean
def map[@specialized(Int, Boolean) B](f: A => B) =
//..
}