Scala基础:Scala泛型

为什么使用泛型

不适用泛型,可能有些变量在编译的过程中不能发现,在执行的时候才能发现。

类型的约束,使用泛型之后,只有使用规则的数据才能使用。

泛型代码示例

object GenericApp {

  def main(args: Array[String]): Unit = {

    new WeChatMsg("wechat message")
    new DigitMsg(200)
    
    val man1 = new Man[String, Int, HobbyEnum]("zhangsan", 70, HobbyEnum.BASEBALL)
    val man2 = new Man[String, Int, HobbyEnum]("lisi", 80, HobbyEnum.BASEBALL)
    val man3 = new Man[String, Int, HobbyEnum]("wangwu", 90, HobbyEnum.BASEBALL)

    println(man1)
    println(man2)
    println(man3)
  }
}

//最顶层是个任意类型
abstract class Msg[T](content: T)

//WebChatMsg 和 DigitMst对类型进行了约束
class WeChatMsg[String](content: String) extends Msg(content) {
  println(content)
}

class DigitMsg[Int](content: Int) extends Msg(content) {
  println(content)
}

class Man[A, B, C](val name: A, val height: B, val hobby: C) {

  override def toString: String = s"$name\t$height\t$hobby"
}

//Scala枚举的使用
object HobbyEnum extends Enumeration {

  type HobbyEnum = Value
  val SWIM, JUMP, BASEBALL = Value
}

通过Java泛型,对比Scala泛型

Java 泛型

<? extends Test>  ?可以是Test的子类型(T extends Test),这里的 ? 被称为上届(upper bounds)

<? super Test> ?可以是Test的父类型,这里的 ? 被称为下届(lower bounds)

T extends Test,其中 T 为上届( upper bounds),即T的类型最多到Test

下届(lower bounds) <T super Test> T可以是test的父类型 

举例说明Scala的泛型和Java泛型的关系

需求:在scala中实现一个比较两个数大小的函数

如果直接按照需求的语义来写,我们要把scala中的所有数据类型,按照如下的方式写一遍(例子中一Int和Long举例)

object UpperLowerBoundsApp {

  def main(args: Array[String]): Unit = {
    val maxInt = new MaxInt(10, 13)
    println(maxInt.compare)

    val maxLong = new MaxLong(10, 13)
    println(maxLong.compare)
  }
}

class MaxInt(x: Int, y: Int) {

  def compare: Int = if (x > y) x else y
}

class MaxLong(x: Long, y: Long) {
  def compare: Long = if (x > y) x else y
}

在scala中,可以通过泛型的方式来实现,但是在使用的过程中,需要注意一个点:

Scala中的所有值类的基类是AnyVal,即所有值类都是使用AnyVal接口来实现的,它并没有实现Comparable接口。

但是java中的数值是通过Comparable接口来实现的,所以我们在scala中调用泛型的时候,需要将数值类型定义为java中的数值类型。

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)
  }

}

/**
 * 上届
 * <: T是Comparable 这个类的子类型,即T必须是Comparable的子类(或本身,自己也可以认为是自己的子类)
 *
 * @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
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值