天天看点

Scala学习笔记

1类型自动匹配(模式匹配)

2函数是有值的(匿名函数是函数的常态)

递归函数需要指定返回值

3.内部类隶属于外部类的实例本身,而java内部类属于外部类,对外部类的依赖路径依赖

4.object类似于java中的静态内部类 里面的所有成员都是静态的,适用于配置文件

静态都是用来修饰类的内部成员的。比如静态方法、静态成员变量。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生,以致可以用类名+静态成员名直接获得。这样静态内部类就可以理解了,它可以直接被用 外部类名+内部类名 获得。

5.同名object是class的伴生对象,很多时候伴生对象是做为伴生类静态成员的封装区域

6.scala方法的最后一行是返回值无return

7.scala可变参数int*  java中 int... args

8.apply使用与单例

<a href="http://book.51cto.com/art/201408/449448.htm" target="_blank">http://book.51cto.com/art/201408/449448.htm</a>

9.接口trait(可以有非抽象方法)比 interface (只能有抽象方法) 功能强大很多  extends ..... with....with....

跟java一样只能继承一个trait或者class,如果还要继承其他trait需要with(对象混入)

10. 包对象(package object)  包中所有类可以直接访问包对象的所有成员和方法

11scala包的隐式引用

import java.lang._

import scala._

import predef._

12.映射符号 =&gt; lambda表达式,表示一个匿名函数

13.占位符  _  placeholder 模式匹配代表字符串

14. 本地函数 在函数中定义的函数,内部函数属于私有函数,外部不可以访问,实现高内聚低耦合

15.偏函数 _ 代表参数 编译器根据sum _ (空格+下划线)自动产生类里的apply方法 传递部分参数变成另外一种函数

16.闭包 javascript支持 闭包就是能够读取其他函数内部变量的函数,由于javascript的语言特性,如果你想读取一个函数内部的变量,那你本身也必须是这个函数内部子函数。

17.高阶函数 map() 以函数作为参数

18.模式匹配与提取器 extrator

                      match

                      case

模式匹配在具体数据类型的上的应用

19.正则表达式后面带个.r

20.scala的case class和pattern

matching(模式匹配),这俩个两个程序结构对于处理树结构的数据非常有帮助。scala的case

class使得对对象进行模式匹配变得非常方便,简单的来说,scala的case

class就是在普通的类定义前加case这个关键字,然后你可以对这些类来模式匹配。

成员默认是val的,成员未显式声明var或者val的话,默认是val(常量)

每个case class都会有伴生对象里面有apply方法

伴生对象会帮我们构造出case class的具体对对象

unapply从已经构建出的对象中(case class or object)提取出内容,而伴生对象的apply方法是构建对象

21 构造器的函数名为this,重载构造器(附属构造器)必须要调用其他的附属构造器,其他的构造器在最终形态上会调用主构造器,scala函数若没有参数省略小括号,this()可以简写成this

22.  别名 @符号可以引用匹配到的对象 index@"flink"

23 sealed封闭   只能在当前文件里头被继承,限制子类必须在同一个文件中

option 的两个子类 some none

24.两个::表示往list头部添加元素,三个:::组合list,list集合分为head(第一个)和tail两部分

val hadoop= new hadoop ::nil

25.拉链操作 zip

26.flatmap  集合map后合并多个集合

27.list更多操作  partition(分区) span  find(第一个满足条件的元素) takewhile  dropwhile 

exists (有一个满足返回true) forall (全部满足返回true)

28.foldleft  foldright从最左边开始和最右边开始  sortwith(_&lt;_)排序操作

29. list.range(2,5)   半闭半开区间  list(2,3,4)不包括5

30.list.map2同时对两个集合相应元素操作

31.可变集合需要引入mutable包,默认是不可变的集合

可变集合可以直接用+=和-=追加删除元素,++=和--=追加删除集合

32.hashmap非常高效的,对key进行hashcode取值

33.treemap,treeset有序的

34.list[+a]协变

35. &lt;- 提取符号(迭代器)

37. f 代表函数

38. bounds 类型限定符号

                                         &lt; :  上界   只能是子类

                                         &gt; :  下界   只能是父类

              更常用             &lt; %  视图界定 不是子类会隐式转换  int -&gt;richint string-&gt;richstring

39.  ordered[t]对象可以用&gt;或者&lt;符号比较对象代替comparable[t]的comapreto方法

40. [t  : ordering] context bounds 上下文界定 存在一个类型为ordering[t]的隐式值

   spark大量使用

41. [t : manifest]  内部自动构建manifest类型的隐式参数 implicit

      [t : classtag]  编译时会自动翻译成隐式参数和隐式值

      虚拟机运行时泛型是擦除的,不认识泛型 ,必须给具体的类型

42. 理解即可 类型约束   a &lt; : &lt; b  a必须是b的子类比&lt; :更严格,编译的时候就会去判断类型

                       a=:=b  a和b是同类型  

43.    [+a] covariance(协变)  [-a] contravariance(逆变)

如果一个类型支持协变或逆变,则称这个类型为variance(翻译为可变的或变型),否则称为invariant(不可变的)

先说说协变和逆变(实际上还有非变)。协变和逆变主要是用来解决参数化类型的泛化问题。由于参数化类型的参数(参数类型)是可变的,当两个参数化类型的参数是继承关系(可泛化),那被参数化的类型是否也可以泛化呢?java中这种情况下是不可泛化的,然而scala提供了三个选择,即协变、逆变和非变。下

面说一下三种情况的含义,首先假设有参数化特征queue,那它可以有如下三种定义。

1)trait queue[t] {}

这是非变情况。这种情况下,当类型s是类型a的子类型,则queue[s]不可认为是queue[a]的子类型或父类型,这种情况是和java一样的。

2)trait queue[+t] {}

这是协变情况。这种情况下,当类型s是类型a的子类型,则queue[s]也可以认为是queue[a}的子类型,即queue[s]可以泛化为queue[a]。也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变。

3)trait queue[-t] {}

这是逆变情况。这种情况下,当类型s是类型a的子类型,则queue[a]反过来可以认为是queue[s}的子类型。也就是被参数化类型的泛化方向与参数类型的方向是相反的,所以称为逆变。

44. 默认情况下只要方法(函数)是泛型的,它的参数是逆变的,返回值就是协变的

scala规定,协变类型只能作为方法的返回类型,而逆变类型只能作为方法的参数类型。类比函数的行为,结合liskov替换原则,就能发现这样的规定是非常合理的。

里氏替换原则(liskov substitution principle lsp)

      里氏替换原则是面向对象设计的基本原则之一。任何基类可以出现的地方,子类一定可以出现。lsp是继承复用的基石,只有当子类可以替换基类,软件单位的功能不受影响时,基类才能真正的被复用,而子类也可以在基类的基础上增加新的行为。

        里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:

子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

子类中可以增加自己特有的方法。

当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

参考文章:

<a href="http://www.tuicool.com/articles/vaanmq" target="_blank">http://www.tuicool.com/articles/vaanmq</a>

45.this.type表示当前对象(this)的类型,this指代当前的对象。this.type被用于变量,函数参数和函数返回值的类型声明,主要是在某些场合下加强类型约束,或者说是为了确保类型的绝对安全,链式调用

46. type相当于起个别名

47.  spark很少使用 结构类型 不想从类或者接口的角度限制它, 传入的参数包含某种方法

48. 复合类型(extend ....with ....with.... )与结构类型结合使用 

49.infix type (中置类型)  中置表达式(右结合)   :&gt; 代表函数名   中置类型:类型名称写在两个参数中间,泛型的实例在类型的两侧

50.self type 自身类型 self =&gt; 给this实例指针起别名   内部类引用非常方便  this:s1 =&gt;自身类型实例约束必须混入s1

51.鸭子模型与动态语言 不关注类型而关注方法与属性

52.type抽象类型 与 类型参数(语法比较复杂)

type in=string

53.隐式转换总结:查找范围为作用域或者伴生对象

我们需要某个类中特殊方法,但是这个类没有提供这样一个方法,所以我们需要隐式转换成提供了这个方法的类,然后在调用这个方法

需要一个增强类,richint,richfile

隐式转换函数 implicit def

54.隐式参数:有个隐式default值

   参数颗粒化

55.隐式类implicit class

56.隐式对象 implicit object

57.伴生对象隐式转换不需要import

58.并发继承actor编程(akka分布式并发消息驱动框架)  覆写def act(){  }

59.actor工具方法创建匿名actor

   !发消息

    receive中代码块转换成偏函数,说他是偏函数因为返回的计算结果有很多类型

60.  主线程当作actor使用 self.receive{}   main主线程接受其他线给主线程发送的消息

      self.receivewithin()  指定超时时间不会一直阻塞

      sender !  给发送者返回消息

      线程之间使用case class或者class object传递消息

61. react loop 线程重用   替代while(true) { recieve { } }的方式

62.scala swing编程覆写top方法

63. listento(button)  deafto(button) 监听和解除监听

事件栈

    reactions +={

   case buttonclicked(button)=&gt;{

    }

  }

64.for循环中的模式匹配

  for其实调用的是foreach

for((k,v:int) &lt;-list(("spark"-&gt;5),("hadoop"-&gt;"big data"))) { println(k)}

65.模式匹配中不能用大写字母,大写字母会被认为是常量

    模式匹配编译器是lazy级别的,不会报错,运行会报错

66.getclass实例   classof 类型本身

   classof [ ] 更高级别   typeof[  ]更详细级别

67.所有的对象都有一个唯一的.type的单例类型

   this.type构成了链式表达式返回的是动态当前实际运行的实例

68.list的两个子类 class  ::和object nil(空)

69.外在的函数式和内部的可变性是非常精妙的组合

70.for表达式的生成器、定义器、过滤器

 71.play框架

72.for循环取代map,flatmap,filter

73.akka的actor是树状结构( 分层)的共享一些公共信息

  actor有路径  akka://helloakka/user/master

子actor路径

   akka://helloakka/user/master/map

akka://helloakka/user/master/reduce

74.sbt专为scala设计的构建工程  交互式命令操作  安装sbt插件

75.事件驱动的编程模型  消息邮箱

    prestart poststop prerestart

  actorsystem actorref(actor的引用)

 创建actor的过程伴随actor的启动,创建完可以直接发消息

76.actor的构造器 默认的  传入类名   非默认的传入其他actor从而发消息

77. akka中消息的发送方式  (都是异步的)

   1.fire and forget  不等待对方返回结果 java:tell,scala:!

   2.send and receive         java:ask  scala:?   future

   主线程也属于一个actor  在/temp路径下

78.deadletters  消息接受actor死亡

   forward转发会携带原始sender

79.停止actor

shutdown()停止actorsystem

 master!poisonpill  (药丸) 异步的

 master!kill  同步的

 context.stop(self) 异步的

80.monitoring  actor

   watch  unwatch

81.动态切换actor的处理逻辑

  become unbecome