Spark(七):scala类型系统编程实战

一、泛型的操作

  • 背景
    scala的类和方法
    1、函数都可以是泛型,在Spark源码中可以到处看到类和方法的类型,在实际的实例化的时候指定具体的类型
    2、 例如Spark的最核心、最基础、最重要的抽象数据结构RDD里面关于RDD的类的定义是泛型,RDD几乎所有的方法的定义也都是泛型,之所以这么做
    3、是以为内RDD会派生很多的子类,通过子类适配了各种不同的数据源以及业务逻辑
class Animal[T](val species: T) {
  def getAnimal(specie: T)= println(species)
}

通过主函数的调用泛型类并打印出结果。

def main(args: Array[String]): Unit = {
     println( new Animal[String]("wenxuan").getAnimal("123"))
}

二、边界限定

  • 背景
    1、关于对类型边界的限定,分为上边界和下边界
    2、上边界:表达了泛型的类型必须是某种类型或者某种子类,语法为<:,这里的一个新的现象是对类型进行限定
    3、下边界:表达了泛型的类型必须是某种类型或者某种类的父类,语法为>:;
    定义基础的实现类
class Person(val name: String) {
  def talk(person: Person): Unit = {
    println(this.name + ":" + person.name)
  }
}
class Worker(name: String) extends Person(name)

定义泛型类

class Club[T <% Person](p1: T, p2: T) { // <% 隐士转换成person
  def comunicte = p1.talk(p2)
}

实例化类,实例化泛型类

val p = new Person("Scala")
val w = new Worker("Spark")
new Club[Person](w, dog).comunicte

三、View Bounds的视图界定

  • 背景:
    1、Viwe Bounds,可以进行某种神秘的转换,把你的类型可以在没有只觉得情况下转成为目标类型,其实你可以认为View Bounds是上边界和下边界的加强补充版本
    2、例如在SparkcContext这个Spark的核心类中由T<% Writable方式的代码,这个代码所表达的T必须是Writable类型的,但是T由没有直接继承自Writable的接口,此时就需要通过“implicait的方式”来实现这个功能
    定义功能类
class Dog(val name: String)

class Person(val name: String) {
  def talk(person: Person): Unit = {
    println(this.name + ":" + person.name)
  }
}

定义泛型类

class Club[T <% Person](p2: T, p1: T) { //将T <% 隐士转换成person
 def comunicte = p1.talk(p2)
}

主函数的实现

def main(args: Array[String]): Unit = {
     implicit def dog2Person(dog: Dog) = new Person(dog.name) //把dog转换成person的隐士转换
     val p = new Person("Scala")
     val dog = new Dog("dahuang")
     new Club[Person](w, p).comunicte
|

四、逆变和协变

  • 背景
    逆变和协变:-T和+T
    1、对于一个带类型参数的类型,比如 List[T],如果对A及其子类型B,满足 List[B]也符合 List[A]的子类型,那么就称为covariance(协变)
    父类可以参加即子类可以参加

2、如果 List[A]是 List[B]的子类型,即与原来的父子关系正相反,则称为contravariance(逆变),表达子类可以参加,即父类也可以参加
定义功能类

class Enginner

class Expert extends Enginner

class Meeting[-T]

定义实现函数

  def partitcipateMeeting(meeting: Meeting[Enginner]): Unit = {//协变
def partitcipateMeeting(meeting: Meeting[Eexpert]): Unit = { //逆变

    println("welcome")
  }

主方法的调用

def main(args: Array[String]): Unit = {
     val e = new Meeting[Enginner]
    partitcipateMeeting(e)

    val expert = new Meeting[Expert]
    partitcipateMeeting(expert)
}

五、内容界定

  • 背景:Context Bounds
    T:Ordering这种语法必须能够编程Ordering[T] 这种方式

定义功能类

class Maximum[T: Ordering](val x: T, val y: T) {

  def bigger(implicit ord: Ordering[T])={//将ord隐士转换成Ordering的类型
    if(ord.compare(x,y) >0) x else  y //传入的x,y来比较
  }
}

主函数调用方法

def main(args: Array[String]): Unit = {
      println(new Maximum(2,4).bigger)//可以任意类型
}

你可能感兴趣的:(Spark(七):scala类型系统编程实战)