在 Scala 中所有值都有一种对应的类型

单例类型

  • 形式:value.type,返回类型 value / null

  • 场景1:链式API调用时的类型指定

    class Super {
    def m1(t: Int) = {println(t); this}
    def m2(t: Int) = {println(t); this}
    }
    // 正常打印
    new Super().m1(1).m2(2) class Child extends Super {
    def c1(t: Int) = {println(t); this}
    } // 异常 value c1 is not a member of Super
    new Child().m1(1).c1(2)

    由于 Scala 会将 this 推断为当前类(即 Super),因此无法完成链式调用

    class Super {
    // 指定返回类型为调用方的 this
    def m1(t: Int): this.type = {println(t); this}
    def m2(t: Int): this.type = {println(t); this}
    } class Child extends Super {
    def c1(t: Int) = {println(t); this}
    } // 成功打印
    new Child().m1(1).c1(2)
  • 场景2:方法中使用 object 实例作为参数

    object Foo
    class Child extends Super {
    def c1(obj: Foo.type) = {
    if (obj == Foo) println("foo")
    this
    }
    }

    Note:不可定义为 def c1(obj: Foo),因为 Foo 为单例对象,而不是类型

类型投影

  • 形式:Outer#Inner

  • 场景:内部类使用时避免类型约束

    class Outer {
    private val inners = ArrayBuffer[Inner]() class Inner (val arg1: Int) {
    val l = ArrayBuffer[Inner]()
    } def add(a: Int) = {
    val t = new Inner(a)
    inners += t
    t
    }
    } val a = new Outer
    val b = new Outer val a1 = a.add(1)
    val b1 = b.add(1)
    a1.l += b1 // error: type mismatch;

    只需要在定义内部类时指定类型投影即可解决

    // 表示适用于任何 Outer 类的 Inner 类
    val l = ArrayBuffer[Outer#Inner]()

    如果将上述例子改用 List 来实现,并不会报错,计算结果也会自动进行类型投射

路径

  • 路径中除最后一部分外,都必须是稳定状态的,如包名、objectvalthis/super/super[S]...

  • 不能包含 var 类型

    var t = new Outer()
    //...其他操作
    val i = new t.Inner // 由于 t 可能会变更,编译器无法确定其含义

    a.b.c.T 内部被翻译成类型投射 a.b.c.type#T

类型别名

  • 形式: type SomeAliasName

  • 必须定义在 classobject 内部

  • 好处: 在引用类型时可以更加简洁

    class Book {
    import scala.collection.mutable._
    // 为该类型取一个别名
    type Index = HashMap[String, Int] // 使用时不在需要重复的定义复杂的数据类型
    val map: Index = new Index()
    } new Book().map // scala.collection.mutable.HashMap[String,Int]

结构类型

  • 为抽象方法、字段、类型的定义某种规范

    def appendLines(target: { def append(str: String): Any },
    lines: Iterable[String]) {
    for (l <- lines) {
    // 此次 Scala 使用反射调用该方法
    target.append(l);
    target.append("\n")
    }
    }

    该方法第一个参数 target 即结构类型,表示使用任何包含该 append 方法的实例作为参数传入。

    由于反射的代价较大,不到万不得已不建议使用,如,有通用行为(append),却无法共享 trait

组合类型 / 交集类型

  • 形式: T1 with T2 with T3 ...

  • 当需要提供多个特质时使用,即用于约束类型

    val image = new ArrayBuffer[java.awt.Shape with java.io.Serializable]
    val rect = new Rectangle(5, 10, 20, 30)
    image += rect // 正确,Rectangle 可序列化
    image += new Area(rect) // 错误 Area 不可序列化
  • 组合类型中也可使用结构类型

    Shape with Serializable { def contains(p: Point): Boolean }

中缀类型

  • 其实只是一种语法写法,如 String Map Int 可代替 Map[String, Int]

  • 可参考数学运算中的表达方式

    type x[A, B] = (String, Int)
    // 即可使用 String x Int 来表示 (String, Int)
  • 一般中缀类型操作符都是左关联的,除了前面提到的 : 操作符,这个是右关联的,比如 List 的操作

中缀类型名称可以是任意操作符,除了 *,避免与类型定义冲突

Scala Types 1的更多相关文章

  1. Scala: Types of a higher kind

    One of the more powerful features Scala has is the ability to generically abstract across things tha ...

  2. Scala Types 2

    存在类型 形式: forSome { type ... } 或 forSome { val ... } 主要为了兼容 Java 的通配符 示例 Array[_] // 等价于 Array[T] for ...

  3. 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 ...

  4. scala速成记录1

    选择  Learning Scala这本书,两百多页,足够薄. 安装 http://www.scala-lang.org/  下载Binary的版本.bin里边有所有操作系统下运行的可以运行的交互式s ...

  5. geotrellis使用(十九)spray-json框架介绍

    Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html 目录 前言 spray-json简介 spray-json使用 ...

  6. Akka(33): Http:Marshalling,to Json

    Akka-http是一项系统集成工具.这主要依赖系统之间的数据交换功能.因为程序内数据表达形式与网上传输的数据格式是不相同的,所以需要对程序高级结构化的数据进行转换(marshalling or se ...

  7. 【原创】大叔问题定位分享(11)Spark中对大表子查询加limit为什么会报Broadcast超时错误

    当两个表需要join时,如果一个是大表,一个是小表,正常的map-reduce流程需要shuffle,这会导致大表数据在节点间网络传输,常见的优化方式是将小表读到内存中并广播到大表处理,避免shuff ...

  8. Spark SQL 函数全集

    org.apache.spark.sql.functions是一个Object,提供了约两百多个函数. 大部分函数与Hive的差不多. 除UDF函数,均可在spark-sql中直接使用. 经过impo ...

  9. org.apache.spark.sql.functions汇总

    测试数据: id,name,age,comment,date 1,lyy,28,"aaa bbb",20180102020325 scala> var data = spar ...

随机推荐

  1. vue Router——基础篇

    vue--Router简介 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用. vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路 ...

  2. FCC-学习笔记 Pig Latin

    FCC-学习笔记  Pig Latin 1>最近在学习和练习FCC的题目.这个真的比较的好,推荐给大家. 2>中文版的地址:https://www.freecodecamp.cn/;英文版 ...

  3. 前端H5知识总结

    两年大专生活匆匆而过,身边的朋友也都各奔东西,9月份开始实习感觉自己的前端功底有所欠缺,这个暑假除了打工我还有一个半月的学习时间希望自己能够充分利用这段时间.7月3号所学知识在此做以下总结以便自己复习 ...

  4. oracle高级部分

    回顾 多表关联查询的方式 内连接 根据AB表关联的条件进行过滤查询,只保留满足条件数据 Select * from a,b where a.xxx=b.xxx; Select * from a inn ...

  5. flink dataset join笔记

    1.dataset的join连接,通过key进行关联,一般情况下的join都是inner join,类似sql里的inner join key包括以下几种情况: a key expression a ...

  6. Kubernetes概念之RC

    感觉自己浪费了一年的时间,种一棵树最好的时间是十年前,还有就是现在,虽然这颗树种了又种,种了又种,这次真的要种了......   本文通过<Kubernetes权威指南>的概念部分学习总结 ...

  7. django2外键,F表达式,Q表达式

    一对多 环境 两个类:书的类别和文章,一片文章只能有一个作者,一个作者可以有多个文章,这之间组成了一对多的关系 class Category(models.Model): category = mod ...

  8. 等了半年的AMD锐龙3000系列台式机处理器今天终于上市开卖了!

    第三代AMD锐龙台式机处理器参数:

  9. destoon中get_maincat函数的用法

    求解get_maincat函数的用法,如get_maincat(0, $CATEGORY, 1),其中第一.二.三个参数分别表示什么,有谁知道,请介绍下,谢谢! 答:get_maincat() 三个参 ...

  10. Linux下使用cx_Oracle的一些配置

    在安装完成cx_Oracle后,import  cx_Oracle时报错,首先查看.bash_profile文件中环境变量配置 # .bash_profile # Get the aliases an ...