zoukankan      html  css  js  c++  java
  • Scala学习——泛型[T]的6种使用(初)

     1 package com.dtspark.scala.basics
     2 
     3 /**
     4  * 1,scala的类和方法、函数都可以是泛型。
     5  * 
     6 
     7  * 2,关于对类型边界的限定分为上边界和下边界(对类进行限制)
     8  * 上边界:表达了泛型的类型必须是"某种类型"或某种类型的"子类",语法为“<:”,
     9  * 下边界:表达了泛型的类型必须是"某种类型"或某种类型的"父类",语法为“>:”,
    10  * 
    11 
    12  * 3, "<%" :view bounds可以进行某种神秘的转换,把你的类型在没有知觉的情况下转换成目标类型,
    13  * 其实你可以认为view bounds是上下边界的加强和补充,语法为:"<%",要用到implicit进行隐式转换(见下面例子)
    14  * 
    15 
    16  * 4,"T:classTag":相当于动态类型,你使用时传入什么类型就是什么类型,(spark的程序的编译和运行是区分了Driver和Executor的,只有在运行的时候才知道完整的类型信息)
    17  * 语法为:"[T:ClassTag]"下面有列子
    18  *
    19 
    20  * 5,逆变和协变:-T和+T(下面有具体例子)+T可以传入其子类和本身(与继承关系一至)-T可以传入其父类和本身(与继承的关系相反),
    21  * 
    22 
    23  * 6,"T:Ordering" :表示将T变成Ordering[T],可以直接用其方法进行比大小,可完成排序等工作
    24  */
    25 
    26 class Person(val name:String){
    27   def talk(person:Person){
    28     println(this.name+" speak to "+person.name)
    29   }
    30 }
    31 
    32 class Worker(name:String)extends Person(name)
    33 
    34 class Dog(val name:String)
    35 
    36 
    37 
    38 
    39 //注意泛型用的是[]
    40 class Club[T<:Person](p1:T,p2:T){//"<:"必须是person或person的子类
    41   def comminicate = p1.talk(p2)
    42 }
    43 
    44 
    45 class Club2[T<%Person](p1:T,p2:T){
    46   def comminicate = p1.talk(p2)
    47 }
    48 
    49 class Engineer
    50 class Expert extends Engineer
    51 //如果是+T,指定类型为某类时,传入其子类或其本身
    52 //如果是-T,指定类型为某类时,传入其父类或其本身
    53 class Meeting[+T]//可以传入T或T的子类
    54 
    55 class Maximum[T:Ordering](val x:T,val y:T){
    56   def bigger(implicit ord:Ordering[T])={
    57     if(ord.compare(x, y)>0)x else y
    58   }
    59 }
    60 
    61 object HelloScalaTypeSystem {
    62   def main(args: Array[String]): Unit = {
    63      val p= new Person("Spark")
    64      val w= new Worker("Scala")
    65      new Club(p,w).comminicate
    66      
    67 //"<%"的列子
    68      //只是提供了一个转换的方法,在遇到<%时会调用看dog是否被转换了。
    69      implicit def dog2Person(dog:Dog)=new Person(dog.name)
    70      val d = new Dog("dahuang")
    71      //注意必须强制类型转换,implicit中虽然是将dog隐式转换成person,
    72      //但是其实是对象擦除,变成了object,所以还要强制类型转换成person后才能使用
    73      //用[person]强制转换
    74      new Club2[Person](p,d).comminicate
    75      
    76  //-T +T例子,下面的participateMeeting方法指定具体是什么泛型
    77      val p1=new Meeting[Engineer]
    78      val p2=new Meeting[Expert]
    79      participateMeeting(p1)
    80      participateMeeting(p2)
    81  // T:Ordering 的例子   
    82      println(new Maximum(3,5).bigger)
    83      println(new Maximum("Scala","Java").bigger)
    84 
    85      
    86      
    87   }
    88   //这里指定传入的泛型具体是什么
    89   def participateMeeting(meeting:Meeting[Engineer])=  println("welcome")
    90   
    91 }

    T:ClassTag的例子(根据输入动态定义)

    命令行代码:

    scala> import scala.reflect.ClassTag
    import scala.reflect.ClassTag
    
    scala> def mkArray[T: ClassTag](elems: T*) = Array[T](elems: _*)
    mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T]
    
    
    scala> mkArray(1,2,3)
    res1: Array[Int] = Array(1, 2, 3)
    
    scala> mkArray("ss","dd")
    res2: Array[String] = Array(ss, dd)
    scala> mkArray(1,"dd")
    res2: Array[Any] = Array(1, dd)

     

  • 相关阅读:
    HttpServletRequest对象(转)
    HttpServletResponse对象(转)
    springboot+mybatis 用redis作二级缓存
    springboot+JPA 整合redis
    如何使用RedisTemplate访问Redis数据结构之Zset
    如何使用RedisTemplate访问Redis数据结构之Hash
    如何使用RedisTemplate访问Redis数据结构之list
    如何使用RedisTemplate访问Redis数据结构之字符串操作
    Spring Boot中使用Swagger2构建强大的RESTful API文档
    Centos之目录处理命令
  • 原文地址:https://www.cnblogs.com/LazyJoJo/p/6410509.html
Copyright © 2011-2022 走看看