scala基础:scala 泛型中的符号

发布时间 2023-03-24 09:50:12作者: Netsharp

泛型中的符号

符号 作用
[T <: UpperBound] 上界
[T >: LowerBound] 下界
[T <% ViewBound] 视界
[T : ContextBound] 上下文界
[+T] 协变
[-T] 逆变

关于各个泛型符号的详解

1. 上下界约束符号 <: 与 >:

class MaxValue[T <: Comparable[T]](x:T,y:T){
 
  def compare:T = if (x.compareTo(y)>0) x else y
}

例子中

MaxValue[T <: Comparable[T]]

是上届的定义,也就是T必须是Comparable的子类(或本身,自己也可以认为是自己的子类)。

同理,如果

MaxValue[T >: Comparable[T]]

就下届的定义,也就是T必须是Comparable的父类(或本身,自己也可以认为是自己的子类)。

2.view bounds(视界) 符号 <%

//视图界定:底层隐式转换了
class MaxValue2[T <% Comparable[T]](x:T,y:T){
 
  def compare:T = if (x.compareTo(y)>0) x else y
}

它比<:适用的范围更广,除了所有的子类型,顶层做了隐式转换,允许scala中的数据类型调用。

下面举例说明 <: 和 <:在实际使用中的差异

object UpperLowerBoundsApp {
 
  def main(args: Array[String]): Unit = {
    /**
     * 我们如果直接使用 <: 来定义泛型来实现底层接口,在使用的时候会有如下问题
     * val maxValue = new MaxValue[Int](10,13)
     *
     * Error type arguments [Int] do not conform to class MaxValue's type parameter bounds [T <: Comparable[T]]
     * val maxValue = new MaxValue[Int](10,13)
     *
     * 报错原因:
     * scala中Int的源码:final abstract class Int private extends AnyVal
     * 因此 scala并没有实现Comparable接口与
     *
     * 但是 java 里的Integer public final class Integer extends Number implements Comparable<Integer>
     * java里的Integer是按照comparable来实现的
     */
    val maxValue1 = new MaxValue[Integer](10,13)
    val maxValue2 = new MaxValue(Integer.valueOf(10),Integer.valueOf(13))
 
    println(maxValue1.compare)
    println(maxValue2.compare)
 
    /**
     * <: 定义的泛型,因为scala的数据类型没有实现comparable接口,不得不掉调用java底层的数据类型来实现
     * 但是,在scala中,可以使用 <% 或者 >% 定义泛型,来直接在泛型中使用
     * 这样能够使用scala 中的数据类型的原因是,在scala中,通过隐式转换的方式,是的 <% 既能实现comparable接口,有能兼容scala中的数据类型
     */
    val maxValue3 = new MaxValue2(10,13)
    println(maxValue3.compare)
  }
 
}
 
/**
 * 上届
 * @tparam T
 */
class MaxValue[T <: Comparable[T]](x:T,y:T){
 
  def compare:T = if (x.compareTo(y)>0) x else y
}
 
//视图界定:底层隐式转换了
class MaxValue2[T <% Comparable[T]](x:T,y:T){
 
  def compare:T = if (x.compareTo(y)>0) x else y
}