类型参数

  • 表现形式:在名称后面以方括号表示, Array[T]

  • 何处使用

    • class 中,用于定义变量、入参、返回值

      class Pair[T, S](val first: T, val second: S)
      // scala 可自动推断具体的类型
      val p = new Pair(42, "String") // Pair[Int, String]
    • 函数、方法

      def getMiddle[T](a: Array[T]) = a(a.length / 2)
  • 类型边界

    • 上边界 T <: UpperBound

      // 比较大小
      class Pair[T](val first: T, val second: T) {
      def smaller = if (first.compareTo(second) < 0) first else second
      }

      无法确定 first 是否存在 compareTo 方法,所以必须添加约束,fist 必须是 Comparable 的子类型,即需要添加上边界

      class Pair[T <: Comparable[T]](val first: T, val second: T) {
      def smaller = if (first.compareTo(second) < 0) first else second
      }
    • 下边界 T >: LowerBound

      // 替换第一个元素
      class Pair[T](val first: T, val second: T) {
      def replaceFirst(newFirst: T) = new Pair[T](newFirst, second)
      }

      替换第一个元素为 T 的父类 R,那么返回类型是什么? 如果需要返回 R,则需要添加约束,即需要下边界;否则返回的类型为 Any

      // 返回类型自动推断为 new Pair[R]
      def replaceFirst[R >: T](newFirst: R) = new Pair(newFirst, second)
    • 上下文边界 T : ContextBound

      Scala 2.8 对 Array 进行了更新优化,使用隐式转换和 manifest 将数组整合为 Scala 的集合库

      def tabulate[T](len: Int, f: Int => T)(implicitm: ClassManifest[T]) = {
      val xs = new Array[T](len)
      for(i <- 0 until len) xs(i) = f(i)
      xs
      } // 简化后
      def tabulate[T: ClassManifest](len: Int, f: Int => T) = {
      val xs = new Array[T](len)
      for(i <- 0 until len) xs(i) = f(i)
      xs
      }
      • ClassTag, 指定运行时的类型,如 Array[Int] 在运行时想指定为 int[]

        import scala.reflect._
        def makePair[T : ClassTag](first: T, second: T) = {
        val r = new Array[T](2); r(0) = first; r(1) = second; r
        } makePair(4, 9) // 实际调用
        makePair(4, 9)(classTag) // new 操作,即 ClassTag[Int] 构建原始类型数组 int[2]
        classTag.newArray
    • 多个边界

      • 可同时添加上界和下界 T >: Lower <: Upper
      • 不可添加多个上界或多个下届,但可实现多个 trait,
        • T <: Comparable[T] with Serializable with Cloneable
      • 可指定多个上下文边界 T : Ordering : ClassTag
  • 类型约束

    • 测试是否相等 T =:= U
    • 测试是否为子类 T <:< U
    • 测试是否可转换 T => U

    要添加该约束,需添加隐式参数

    // 约束类
    class Pair[T](val first: T, val second: T)(implicit ev: T <:< Comparable[T]) // 约束方法调用,只有类型满足才能调用成功,否则报错
    class Pair[T](val first: T, val second: T) {
    def smaller(implicit ev: T <:< Ordered[T]) =
    if (first < second) first else second
    } // 便于类型推断
    def firstLast[A, C <: Iterable[A]](it: C) = (it.head, it.last)
    // 无法推断类型 A
    firstLast(List(1, 2, 3)) // [Nothing, List[Int]]
    // 添加约束关系
    def firstLast[A, C](it: C)(implicit ev: C <:< Iterable[A]) = (it.head, it.last)

Scala Type Parameters 1的更多相关文章

  1. Scala Type Parameters 2

    类型关系 Scala 支持在泛型类上使用型变注释,用来表示复杂类型.组合类型的子类型关系间的相关性 协变 +T,变化方向相同,通常用在生产 假设 A extends T, 对于 Clazz[+T],则 ...

  2. Beginning Scala study note(8) Scala Type System

    1. Unified Type System Scala has a unified type system, enclosed by the type Any at the top of the h ...

  3. type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds int,java.lang.Object

    今天在进行代码检查的时候出现下面的异常: type parameters of <T>T cannot be determined; no unique maximal instance ...

  4. Java Error : type parameters of <T>T cannot be determined during Maven Install

    遇到了一个问题如下: Caused by the combination of generics and autoboxing. 这是由于泛型和自动装箱联合使用引起的. 可以查看以下两个回答:   1 ...

  5. learning scala type alise

    How to use type alias to name a Tuple2 pair into a domain type called CartItem type CartItem[Donut, ...

  6. learning scala repreated parameters

  7. Scala 深入浅出实战经典 第78讲:Type与Class实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  8. scala类型系统 type关键字

    和c里的type有点像. scala里的类型,除了在定义class,trait,object时会产生类型,还可以通过type关键字来声明类型. type相当于声明一个类型别名: scala> t ...

  9. Scala Reflection - Mirrors,ClassTag,TypeTag and WeakTypeTag

    反射reflection是程序对自身的检查.验证甚至代码修改功能.反射可以通过它的Reify功能来实时自动构建生成静态的Scala实例如:类(class).方法(method).表达式(express ...

随机推荐

  1. 【转】LockSupport深入浅出

    原文:https://www.cnblogs.com/qingquanzi/p/8228422.html 本篇是<自己动手写把"锁">系列技术铺垫的最后一个知识点.本篇 ...

  2. Redis 分布式锁的正确打开方式

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  3. JMETER 使用断言

    断言概念 断言就是在执行某个请求后,根据返回的结果,判断返回是否正确,如果不正确,则表示事务失败. 添加断言 启动流程时返回的数据是一个 json对象,结构为 {success:true,msg:&q ...

  4. Python 和 R 中的一数多图

    R # 一数多图 x <- 2:6 y <- 7:3 y1 <- y +2 opar <- par(no.readonly = TRUE) par(mfrow=c(2, 3)) ...

  5. 显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么?

    在使用深度学习框架的过程中一定会经常碰到这些东西,虽然anaconda有时会帮助我们自动地解决这些设置,但是有些特殊的库却还是需要我们手动配置环境,但是我对标题上的这些名词其实并不十分清楚,所以老是被 ...

  6. Nginx——端口负载均衡

    前言 Nginx做的代理后面SpringBoot的项目,1N3T的架构,Tomcat的配置也进行了相应的调优. 配置 这里主要来简单的说下Nginx的端口负载均衡,具体的大家可以参考 Nginx文档 ...

  7. 11-C#笔记-函数-方法

    # 1 函数基本使用 函数的调用方法用C++. 主函数要在一个Class中,静态的,无返回值: 见示例 using System; namespace CalculatorApplication { ...

  8. JZOJ3492数数&&GDOI2018超级异或绵羊——位&&类欧几里得

    JZOJ3492 数数(count) 我们知道,一个等差数列可以用三个数A,B,N表示成如下形式:  B+A,B+2A,B+3A⋯B+NA ztxz16想知道对于一个给定的等差数列,把其中每一项用二进 ...

  9. hdu1005-Number Sequence-(循环节)

    题意:已知f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7,给出A,B,n,求f(n) 题解:n巨大,循环肯定超时,在模7的 ...

  10. 阿里巴巴java开发手册 注释规约