美文网首页
Spark(三) scala復雜語法之泛型

Spark(三) scala復雜語法之泛型

作者: 文子轩 | 来源:发表于2018-08-20 23:35 被阅读41次

一.初解

当构建一个类或者函数时,如果我们不知道(或者说不确定)传入的参数的具体数据类型,这时候可以泛型,例子如下:

  • 1-1例子:
object test0 extends App{
   val str = "123"
   val intv =123
   val strTest = new Test[String](str)
   val intTest = new Test[Int](intv)
   strTest.check;
   intTest.check;
}
class Test[T](val v:T){
  def check = {
    if(v.isInstanceOf[String]){
      println("the param is String");
    }
    if(v.isInstanceOf[Int]){
      println("the param is Int");
    }
  }
}
  • 結果

    the param is String
    the param is Int

  • 結論

很多时候我们都需要用到泛型,在web中最常见的就是在用java构建DAO层时,我们往往不知道传入的类型是什么,但是很多时候的操作都是一样的,如增删改查。用泛型+反射的模式可以写一个基于上述操作的通用的模板让所有的需要访问数据库的service层类去调用

二.界定(Bonds)

  • 2-1 例子
    class Pair[T](val first:T,val second:T){
      def smaller = if(first.compareTo(second) < 0) first else second //编译器报错,因为编译器不能确定T具有compareTo的方法
    }
    object test1 extends App{
      val a="3"
      val b = "2"
      val pair = new Pair(a,b);
      print(pair.smaller);
    }

所以改進如下

class Pair[T<:Compareable[T]](val first:T,val second:T){
  def smaller = if(first.compareTo(second) < 0) first else second 
}

修改后就可以运行了。原因是参数的界定是用来限制传入的参数的类型,代表该类型具有这样的一个特性。

  • 2-2 例子
    object test1 extends App{
      val a=3 // 改成整型
      val b =2 // 改成整型
      val pair = new Pair(a,b); // 这里将会报错,因为整型不是Compareable的子类,不具有compareto方法
      print(pair.smaller);
    }

这时候把Pair的界定改成浏览界定<%,这个界定符可以隐式地转换类型

class Pair[T<%Comparable[T]](val first:T,val second:T){
  def smaller = if(first.compareTo(second) < 0) first else second
}
  • 2-3例子
class Pair[T : Ordering](val first: T, val second: T) {
def smaller(implicit ord: Ordering[T]) =
if (ord.compare(first, second) < 0) first else second
}

上下文界定符 “:”意味着可以隐式地转换成Ordering[T]

三.類型約束

类型约束也可以给你用来限制类型,方式有三:
T =:= U
T <:< U
T <%< U
These constraints test whether T equals U, is a subtype of U, or is view-convertible to U.

  • 3-1例子:
 object test3 extends App{
      val first = 123
      val second =346
      val p = new Pair1[Int](first,second) //这里未调用smaller,不报错
      p.smaller;// 这里会报错,因为first,second被检测到不符合
    }
    class Pair1[T](val first: T, val second: T){

      // 下面的方法调用了类型约束,当被调用时才会检测约束
  def smaller(implicit ev: T <:< Comparable[T]) =
          if (first.compareTo( second) < 0) first else second
    }

四.視圖界定

泛型视图限定:表示把传入不是Comparable[T]类型的隐式传换为Comparable[T]类型,Comparable[T]:为T下界,T:为Comparable[T]上界

 /*
     * <%泛型视图限定符,表示把传入不是Comparable[T]类型的 隐式传换 为Comparable[T]类型
     * Comparable[T]:为T下界,T:为Comparable[T]上界
     */
    class PairNotPerfect[T <% Comparable[T]](val first: T, val second: T) {
      // compareTo方法进行比较,如果大于0返回first
      def bigger = if (first.compareTo(second) > 0) first else second
    }
    
    /*
     * <%泛型视图限定符,表示把传入不是Ordered[T]类型的 隐式传换 为Ordered[T]类型
     * Ordered[T]:为T下界,T:为Ordered[T]上界
     * Ordered继承: extends Any with java.lang.Comparable[A]
     */
    class PairBetter[T <% Ordered[T]](val first: T, val second: T) {
      def bigger = if (first.compareTo(second) > 0) first else second
    }
    
    object ViewVariablesBounds {
      def main(args: Array[String]): Unit = {
        // 函数调用
        var pair = new PairNotPerfect("Spark", "Hadoop");
        // 执行结果:Spark
        println(pair.bigger)
        
        // 函数调用,Int类型进行隐式转换,将Int -> RichInt,RichInt实现了Comparable接口
        var pairInt = new PairNotPerfect(3,5)
        // 执行结果:5
        println(pairInt.bigger);
        
        // 函数调用,Int类型进行隐式转换,将String -> RichString,RichString实现了Comparable接口
        var pairBetterStr = new PairBetter("Java","Scala");
        println(pairBetterStr.bigger);
        
        // 函数调用
        var pairBetterInt = new PairBetter(20, 12);
        // 执行结果:Spark
        println(pairBetterInt.bigger)
      }
    }

五.上下文界定

上下文界定:上下文界定是隐式参数的语法糖。如:Ordering:可以进行隐式转化的T类型。

    class PairOrdering[T: Ordering](val first: T, val second: T) {
      // compareTo方法进行比较,如果大于0返回first
      def bigger(implicit ordered: Ordering[T]) = if (ordered.compare(first, second) > 0) first else second
    }
    
    object ContextBounds {
      def main(args: Array[String]): Unit = {
        // 函数调用
        var pair = new PairOrdering("Spark", "Hadoop")
        // 执行结果:Spark
        println(pair.bigger)
      }
    }

相关文章

  • Spark(三) scala復雜語法之泛型

    一.初解 当构建一个类或者函数时,如果我们不知道(或者说不确定)传入的参数的具体数据类型,这时候可以泛型,例子如下...

  • spark(二) scala復雜語法之隱士轉換

    scala中的隱士轉換操作 隱士轉換的意義 scala提供的隐式转换的特性的作用,简单说就是:当Scala编译器进...

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

    一、泛型的操作 背景scala的类和方法1、函数都可以是泛型,在Spark源码中可以到处看到类和方法的类型,在实际...

  • 好程序员大数据培训分享Scala系列之泛型

    好程序员大数据培训分享Scala系列之泛型,带有一个或多个类型参数的类是泛型的。 泛型类的定义: //带有类型参数...

  • Spark技术实战之基础篇

    Spark技术实战之基础篇 -Scala语言从入门到精通为什么要学习Scala?源于Spark的流行,Spark是...

  • Scala泛型

    泛型类是以类型作为参数,Scala类型参数放在方括号[]中,Java放在<>中 变型 Variance Scala...

  • Scala泛型

    泛型的意思是 泛指某种具体的数据类型 , 在Scala中, 泛型用 [数据类型] 表示. 在实际开发中, 泛...

  • spark应用开发-开发工具篇

    概要 目前Spark官方提供Java,Scala,Python三种语言的API。因为Spark是用Scala开发,...

  • Scala 泛型以及泛型约束

    泛型类 在类声明时,定义一些泛型类型,然后在类的内部,就可以使用这些泛型类型 在需要对类中的某些成员,如字段或方法...

  • Scala 类型系统

    1.在scala泛型中获取其 Class[T] 需求:获取一个泛型 T 的 class 类型的 Class[T],...

网友评论

      本文标题:Spark(三) scala復雜語法之泛型

      本文链接:https://www.haomeiwen.com/subject/vnuriftx.html