Type parameters

Type parameters are defined using square brackets []. If applied to classes and methods, they must be declared before normal parameters, and the result is known as a parameterized type:

case class Wrapper[A](content: A) {
def unwrap: A = content
}
def createWrapper[A](a: A):Wrapper[A] = Wrapper(a)
type ConcreteWrapper[A] = Wrapper[A]

val wInt: Wrapper[Int] = createWrapper[Int](10)
val wLong: ConcreteWrapper[Long] = createWrapper(10L)
val int: Int = wInt.unwrap
val long: Long = wLong.unwrap

The Wrapper class is parameterized by the A type. This type parameter is used to refer to the type of content in the unwrap method. The scope resolution rules apply to the type parameters the same way as they do to the normal parameters, as shown by the unwrap method definition.

The createWrapper method definition shows how the type parameter propagates to the implementation side—Wrapper(a) is parameterized with the A type by the compiler. 

The ConcreteWrapper type definition shows that type aliases are parameterized in the same way that types are. 

We then use our parameterized type to demonstrate that it is possible to provide explicit type parameters on the call side, as well as rely on type inference.

This type inference is in fact quite powerful. The compiler always tries to find the most specific type, as the following example reveals (I've provided the explicit type ascriptions, which reflect the types inferred by the compiler):

case class Abc[A](a: A, b: A, c: A)
val intA: Abc[Int] = Abc(10, 20, 30)
val longA: Abc[Long] = Abc(10L, 20L, 30L)
val whatA: Abc[AnyVal] = Abc(10, 20, true)
val whatB: Abc[io.Serializable] = Abc("10", "20", Wrapper(10))
val whatC: Abc[Any] = Abc(10, "20", Wrapper(10))

We discussed Scala's type hierarchy earlier, so it should be obvious how the compiler came up with the types shown in the preceding code snippet.

It is possible to restrict possible definitions of the type parameter by using type constraints, as shown in the following example:

trait Constraints[A <: AnyVal, B >: Null <: AnyRef] {
def a: A
def b: B
}

// compile error - type parameter bounds
// case class AB(a: String, b: Int) extends Constraints[String, Int]

case class AB(a: Int, b: String) extends Constraints[Int, String]

The compiler will check that the concrete definition conforms to the type parameter bounds.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.186.167