泛型与类型变量Bounds初体验与代码实战

参考文献

scala 深入浅出实战经典 . 王家林

场景
scals中泛型的表现形式与 Bounds代码实战
实验
package com.scode.scala
import scala.reflect.ClassTag
/**
 * author: Ivy Peng
 * function: 泛型学习 
 * date:2016/03/26 22.46
 * Generic Type
 * 语法:类名或者方法名后面 【T】or 【T:ClassTag等】
 * Bounds & View Bounds
 * 语法:T <: A  =》 T是A的子类;T>:A => T是A的父类
 *     视图界定 语法举例:  T<% Comparable[T] :T若不是Comparable类型,则隐式转变成Comparable类型,eg、Int => RichInt
 * Context Bounds
 * 概念:在方法申明或者其他语句块中存在隐式的Ordering等信息,在调用方法时不用显性申明参数即可获取参数执行的效果
 * 举例:【T:ClassTag】、【T:Ordering】
 * 
 * ClassTag Manifest ClassManifest TypeTag学习
 * 1、作用:为程序提供class-level runtime infomation,以帮助确定泛型参数具体类型
 * 2、语法:[T:ClassTag]
 * 
 * 
 */

class Triple[F:ClassTag,S,T](val first:F,val second:S,val third:T)

//泛型参数限制:T为 Comparable的子类
class Pair[T<:Comparable[T]](var first:T,var second:T)
{
  
  def bigger=if(first.compareTo(second)>0)first else second
}

class Pair_Lower_Bound[T](val first:T,val second:T)
{
  def replaceFirst[R>:T](newFirst:R)=new Pair_Lower_Bound[R](newFirst,second)
}


//Ordered在Comparable的基础上提供了一些更人性化的操作符
class Pair_NotSoBetter[T<% Comparable[T]](val first:T,val second:T)
{
  def bigger=if(first.compareTo(second)>0)first else second
}
class Pair_Better[T<% Ordered[T]](val first:T,val second:T)
{
  def bigger=if(first>second)first else second
}

class Pair_Ordering[T:Ordering](val first:T,val second:T)
{
  def bigger(implicit ordered:Ordering[T])=//bigger方法存在隐式值
  {
    if(ordered.compare(first, second)>0)first else second
  }
}

object GenericType
{
  def main(args: Array[String]): Unit =
  {
    val pair = new Pair_Ordering("Spark","Hadoop")
    println(pair.bigger)
    val pairInt = new Pair_Ordering(2,3)
    println(pair.bigger)
    
  }
  
  def generic
  {
    //类的泛型化
    var triple = new Triple("nice",80,2)
    val bigData = new Triple[String,Integer,Double]("nice",1,2.0)
    
    //方法的泛型化
    def getData[T](list:List[T])=list(list.length/2)
    println(getData(List("nice","job",123)))
    val f = getData[Int]_
    println(f(List(1,2,3,4)))
    
    //ClassTag 初体验:`ClassTag`s are constructed from knowing only the top-level class of a
    // type, without necessarily knowing all of its argument types
    def buildArray[T:ClassTag](len:Int) = new Array[T](len)
    println(buildArray[Int](5).toList)
    
    //函数一等成员的例子
    def foo[A,B](f:A => List[A],b:A) = f(b)
  }
  def classTag
  {
    def arrayMake[T:Manifest](first:T,second:T):Array[T]=
    {
      var r = new Array[T](2)
      r(0)=first
      r(1)=second
      r
    }
    arrayMake(1,2).foreach(println)
    
    def mkArray[T:ClassTag](elems:T*)=Array[T](elems:_*)
    mkArray(10,20).foreach(println)
    mkArray("Spark","Hadoop","Storm").foreach(println)
    
    def mainf[T](x:List[T])(implicit m:Manifest[T])=
    {
      if(m<:<manifest[String])
        println("list thing")
      else
        println("some thing else")
    }
    mainf(List("Spark","Storm"))
    mainf(List("Scala",3))
  }
  
}

关于Manifest、ClassManifest、TypeTag、ClassType见

http://hongjiang.info/scala-type-system-manifest-vs-typetag/#comments

http://blog.csdn.net/wsscy2004/article/details/38440247

你可能感兴趣的:(泛型与类型变量Bounds初体验与代码实战)