Scala大笔记

Table of Contents

implicit

  1. 修饰函数参数时, 标志该参数不是在调用时必须提供的.
    如果没有提供, 会使用"范围"内的 该类型的默认值, 即用 implicit 定义的值, 或者是 implicit 修饰的返回该类型结果的参数.
    如果没有默认值, 会报编译错误.

简写规则

  1. 函数只有一行代码, 可以去掉大括号和返回类型. 编译器会自动推理.
  2. 如果函数参数是一个函数, 参数函数也只有一个参数 并只使用一次, 那么可以将参数函数 的参数用 _ 代替. 编译器会自动推理.

     class Upper {
       def upper(strings: String*): Seq[String] = {
           strings.map((s: String) => s.toUpperCase())
       }
    }
    
    class Upper {
       def lower(strings:String*) = strings.map(_.toLowerCase())
    }
    
    1. 如果函数只有一看参数, 可以这样写 obj fun param. 这种形式等于 obj.fun(param)

case 关键字

  1. case 修饰类时, 构造函数参数可以直接访问, 但是不能修改其值.
  2. case 修饰的类会在编译时构造一个 companion object.
  3. 创建"companion object"对象时, 编译器会自动寻找 apply()方法, 参数与类相同.
  4. case 会创建很多默认的函数, 如 toString(), hash(), apply()…
  5. copy()函数可以基于一个实例创建另一个实例

规则

  1. scala 中, 整个类定义的代码就是构造函数.
  2. 允许小范围 import
  3. val 修饰的变量是 immutable 的

PartialFunction

  1. 接受任意类型参数, 返回 Unit.
  2. 代码只有 case 组成, 判断接受的参数类型
  3. unexpected 是默认值, 放到 case 的最后

如下形式:

def receive = {
  case s: Shape =>
    s.draw(str => println(s"draw $str"))
    sender ! Response(s" $s drawn")
  case Exit =>
    println("exiting...")
    sender ! Finished
  case unexpected =>
    val response = Response("unkonw")
    println(s"response: $response")
    sender ! response
}
  1. 使用 isDefinedAt 判断是否能 match
  2. 通过 orElse 把多个 PartialFunction 连接起来. 然后判断的时候 会依次做 match
val pf1: PartialFunction[Any, String] = {
  case s: String => "YES"
}
val pf2: PartialFunction[Any, String] = {
  case d: Double => "YES"
}

val pf = pf1 orElse pf2

数据结构

Range

+. 1 to 10 //(1,…,10) +. 1 until 10 //(1,…,9) +. 1 to 10 by 3 //(1, 4, 7 ,10)

函数

  1. 函数参数可以写到多个(一般不超过俩)括号里, 一般第二个括号放 函数参数比较多, 也可以用 "大括号" 代替括号.

    def draw(offset: Point = Point(0.0, 0.0))(f: String => Unit): Unit =    f(s"draw(offset = $offset), ${this.toString}")
    
    s.draw(Point(1.0, 2.0)){
        str => println(s"ShapesDrawingActor: $str")
    }
    

Option, Some, None

  1. Some, 表示有一个数据. None 表示没有数据. 都是 Option 的子类
  2. getOrElse 来获取 Option 中的数据.
  3. map的 getkey 操作返回的都是 Option, 可能为 Some, 也可能为 None

sealed

  1. 该关键字修饰的类, 其子类必须跟该类位于同一个源文件.

_

  1. import 中表示引用所有或者所有的 static
  2. import 中不引入某类型

    import java.math.BigInteger.{
      ONE => _,
      TEN,
      ZERO => JAVAZERO }
    

:

  1. A f: B == B.f(A)
  2. 相当于 Lisp 中的 cons, (相当于修饰符左边是 car, 右边是 cdr) A::B == B.::(A)

if

  1. if 及其他的条件判断语句都有返回值.

for

  1. for (value <- values) action
  2. for (value <- values
    filter
    filter
    ….) action
    也可以在括号中定义变量并使用
  3. 过滤到集合中, yield

    var result = for (value <- values filter) yield value
    

<:

  1. A <: B 表示 A 是 B 的 subclass. 例如 R <: {def close:Unit} 表示 R 是后面的带函数的匿名类的子类.
  2. 实例解析:

    def apply[R <: { def close():Unit }, T](resource: => R)(f: R => T)
    //等于
    def apply[  R <: { def close():Unit },
    	    T ]
    	    (resource: => R)
    	    (f: R => T) = {...}
    
    • R 表示要处理的类型
    • T 表示返回的类型
    • 第一个括号是生成 R 的参数函数
    • 第二个括号是处理 R 并返回结果的参数函数.
  3. <:<(A, B) == A<:<B
  4. Q[A <: B] means that class Q can take any class A that is a subclass of B. Q[+B] means that Q can take any class, but if A is a subclass of B, then Q[A] is considered to be a subclass of Q[B]. Q[+A <: B] means that class Q can only take subclasses of B as well as propagating the subclass relationship.

Created At <2016-08-20 Sat 00:05> by Zhengchao Xu. Email: xuzhengchaojob@gmail.com