Scala 类型系统实战之编程进阶(4)

来源:互联网 发布:网络教育 一对一 加盟 编辑:程序博客网 时间:2024/06/11 02:41

本篇文章主要通过实例来介绍Scala中类型系统的应用:

/* * Scala类型系统编程实战 * 1,Scala的类和方法,函数都可以是泛型,在Spark源码中可以到处看见类和方法的泛型在实际实例化的时候指定类型,例如Spark最核心,最基础,最重要的抽象数据结构RDD里面的类的定义是泛型的,RDD几乎多有的定义都是泛型的,之多以这样做是因为RDD会派生很多子类,通过子类适配了各种不同的数据源以及业务逻辑、 * 2,关于对类型边界的限定,分为上边界和下边界 * 上边界:表达了泛型的类型必须是某种类型或者说是某种类的子类,语法为<:,这里的一个新的现象是对类型进行限定 * 下边界:表达了反省的类型必须是某种类型或者某种类的父类,语法为>: * 3,View Bounds,可以进行某种神秘的转化,把你的类型可以在没有知觉的情况下转化成目标类型上边界和下边界的加强版本,例如在SparkCntext这个Spark核心类 中有 T <% Writable方式的代码,这个代码所表达的是T必须是Writable类型的,但是T有没有直接继承自Writable接口,此时就需要通过“implicit"的方式来实现这个功能 * 4,T : ClassTag,例如Spark源码中的RDD,class RDD[T : ClassTag]这个其实也是一种类型转化系统,只是在编译的时候类型信息不够 * 需要借助JVM的runtime 来通过运行时信息获得完整的类型信息,这在Spark中是非常重啊呀,因为Spark的程序的编程和运行是区分Driver和Executor的,只有在运行的时候才知道完整的类型信息   * ClassTag[T]保存了被泛型擦除后的原始类型T,提供给运行时的。scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*)mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] * 5,逆变和协变 : -T和+T(在这里举个例子,专家和工程师的等级不同的,专家的等级高于工程师,如果在一场会议中,限定了只有专家可以参加,如果此时要求使工程师也可以参加的话此时就得应用逆变,同理工程师可以参加是专家可以参加此时用的是协变原理) * 6,Context Bounds  T : Ordering 这种语法必须能够变成Ordering【T】这种方式 * */class Engineerclass Expert extends Engineerclass Meeting[-T]//类和方法都可以是泛型class Animal[T](val species : T){  def getAnimal(species: T) : T = species}/*class Person(val name : String){  def talk(person : Person){    println(this.name +":"+ person.name)  }}class Worker(name : String) extends Person(name)class Dog(name : String)//此时应用了<%与 implicit的方法合用的案例implicit def dog2Person(dog: Dog) = new Person(dog.name)class Club[T <% Person](p1 : T,p2 : T){  def comunicate = p1.talk(p2)}*//*class Club[T <: Person](p1 : T,p2:T){  def comunicate = p1.talk(p2)}*/class Maximum[T : Ordering](val x : T,val y : T){  def bigger(implicit ord : Ordering[T]) = {    if(ord.compare(x, y) > 0) x else y  }}object HelloScalaTypeSystem {  def main(args: Array[String]): Unit = {  /*  implicit def dog2Person(dog: Dog) = new Person(dog.name)    val p = new Person("Scala")    val w = new Worker("Spark")    val dog = new Dog("dahuang")    new Club(p,w).comunicate    /*类型擦除 所以此时必须定义Club为Person List<String>和List<Int>类型是不一样的,但是jvm运行时会采用泛型擦除。导致List<String>和List<Int>都是Class<List>.为了得到正确的类型,需要通过反射。*/    new Club[Person](p,dog).comunicate*/    val e = new Meeting[Engineer]    participateMeeting(e)    val expert = new Meeting[Expert]    participateMeeting(expert)    println(new Maximum("Scala","Java").bigger)  }      def participateMeeting(meeting : Meeting[Expert]){        println("Welcome")    }  class Person(val name : String){    def talk(person : Person){      println(this.name +":"+ person.name)    }  }class Worker(name : String) extends Person(name)class Dog(val name : String)class Club[T <% Person](p1 : T,p2:T){  def comunicate = p1.talk(p2)} }

本博客内容来自于 : 简介: 王家林:DT大数据梦工厂创始人和首席专家. 联系邮箱18610086859@126.com 电话:18610086859 QQ:1740415547 微信号:18610086859

0 0
原创粉丝点击