scala 泛型 届定 约束

package com.self.study

import scala.reflect.ClassTag

class Genericity {
     

}

// 泛型[], 中括号F \ S \ T 都表示运行时参数类型
// ClassTag[F]保存了泛型擦除后的原始类型F, 提供给被运行时的
class Triple[F: ClassTag, S, T](val first: F, val second: S, val third: T) {
     
  def printClassTag: Unit ={
     
//    println(first.)
  }
}
object HelloTypeParam {
     
  def main(args: Array[String]): Unit = {
     
    // 运行执行代码: val triple: Triple[String, Int, Double]
    val triple = new Triple("Spark", 2, 3.1415)

    // 运行执行代码: val bigData: Triple[String, String, Char]
    val bigData = new Triple[String, String, Char]("Spark", "Hadoop", 'R')

    // getData函数传入泛型为T的运行时List类型参数, 返回list.length / 2的整数
    def getData[T](list: List[T]) = list(list.length /2)

    println(getData(List("Spark", "Hadoop", 'R')))

    val f = getData[Int]_

    println(f(List(1,2,3)))

  }
}

// 泛型类型限定符, 表示只限定Comparable子类
// Comparable[T]: 为T上届, T: 为Comparable[T]下届
class Pair[T <: Comparable[T]] (val first: T, val second: T) {
     
  def bigger = if (first.compareTo(second) > 0) first else second
}

// 声明带T泛型参数的类
class Pair_Lower_Bount[T] (val first: T, val second: T) {
     
  // R是T的父类
  // R: 为T的上届 T为R的下届
  def replaceFirst[R >: T](newFirst: R) = new Pair_Lower_Bount(newFirst, second)
}


// <% 泛型试图届定符, 表示把传入不是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
}

// 上下文界定
class PairOrdering[T: Ordering] (val first: T, val second: T) {
     
  def bigger(implicit ordered: Ordering[T]) = if (ordered.compare(first, second) > 0) first else second
}

object ContextBounds {
     
  def main(args: Array[String]): Unit = {
     
    val pair = new PairOrdering("Spark", "Hadoop")
    println(pair.bigger)
  }
}

// Manifest关键字: 数组在声明时必须要求指定具体的类型, 在函数泛型是无法知道具体类型
// 通过Manifest关键字使得运行时可以根据这个Manifest参数做更多的事情
object ManifestTest {
     
  def main(args: Array[String]): Unit = {
     
    def arrayMake[T: Manifest](first: T, second:T): Array[T] = {
     
      val r = new Array[T](2)
      r(0) = first
      r(1) = second
      r
    }

    arrayMake(1,2).foreach(println)
  }
}

// ClassTag关键字: 保存了泛型擦除后的原始类型T, 提供给被运行时的, 感觉跟Manifest同等效果

// ClassManifest关键字: 在引入Manifest的时候, 还引入了一个更弱一点的ClassManifest
// 所谓的弱是指类型信息不如Manifest那么完整. 用TypeTag替代了Manifest, 用ClassTag替代了
// ClassManifest, 原因是在路径依赖类型中, Manifest存在问题
object ClassManifestTest {
     
  def main(args: Array[String]): Unit = {
     
    class A[T]

    val m = manifest[A[String]]
    println(m)

    val cm = classManifest[A[String]]
    println(cm)

  }
}

// 多重届定(边界确定)符
// T <: A with B => A和B为T的上届
// T >: A with B => A和B为T的下届
// < 或 > 口在哪边, 哪边就是上届; 上下界可以通过族谱来看, 上届是位于上层的父辈, 下届是位于下层的子辈
// T >: A <: B   => 同时拥有上届和下届, 并切A为下届, B为上届, A为B的子类, 顺序不能颠倒
// 以上是泛型中的类型届定
// T : A : B     => 上下文届定, 同时满足A[T]这种隐式值和B[T]这种隐式值
// T <% A <% B   => 试图届定, 即同时能满足隐式转换的A和隐式转换的B 它比<:适用的范围更广,除了所有的子类型, 还允许隐式转换过去的类型

// scala类型约束
// A =:= B 表示A类型等同于B类型
// A <:< B 表示A类型是B类型的子类
object ScalaTypeConstraint {
     
  def main(args: Array[String]): Unit = {
     
    def rocky[T](i: T)(implicit ev:T <:< java.io.Serializable): Unit = {
     
      println("aaa")
    }

    rocky("spark")
  }
}

// 协变[+T]与逆变[-T]
// 协变[+T]: 指能够使用与原始指定的派生类型相比,派生程度更大(子=>父类)的类型。e.g. String => AnyRef,
// 逆变[-T]: 指能够使用派生程度更小(父=>子类)的类型。e.g. AnyRef => String

https://blog.csdn.net/qq_31461055/article/details/82080059
https://blog.csdn.net/bobozhengsir/article/details/13023023

你可能感兴趣的:(scala,scala,泛型,届定)