天天看點

Scala學習筆記

1類型自動比對(模式比對)

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

遞歸函數需要指定傳回值

3.内部類隸屬于外部類的執行個體本身,而java内部類屬于外部類,對外部類的依賴路徑依賴

4.object類似于java中的靜态内部類 裡面的所有成員都是靜态的,适用于配置檔案

靜态都是用來修飾類的内部成員的。比如靜态方法、靜态成員變量。它唯一的作用就是随着類的加載(而不是随着對象的産生)而産生,以緻可以用類名+靜态成員名直接獲得。這樣靜态内部類就可以了解了,它可以直接被用 外部類名+内部類名 獲得。

5.同名object是class的伴生對象,很多時候伴生對象是做為伴生類靜态成員的封裝區域

6.scala方法的最後一行是傳回值無return

7.scala可變參數Int*  java中 int... args

8.apply使用與單例

http://book.51cto.com/art/201408/449448.htm

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

跟java一樣隻能繼承一個trait或者class,如果還要繼承其他trait需要with(對象混入)

10. 包對象(package object)  包中所有類可以直接通路包對象的所有成員和方法

11scala包的隐式引用

import java.lang._

import scala._

import Predef._

12.映射符号 => 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(_<_)排序操作

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. <- 提取符号(疊代器)

37. f 代表函數

38. Bounds 類型限定符号

                                         < :  上界   隻能是子類

                                         > :  下界   隻能是父類

              更常用             < %  視圖界定 不是子類會隐式轉換  Int ->RichInt String->RichString

39.  Ordered[T]對象可以用>或者<符号比較對象代替Comparable[T]的comapreTo方法

40. [T  : Ordering] context bounds 上下文界定 存在一個類型為Ordering[T]的隐式值

   spark大量使用

41. [T : Manifest]  内部自動建構Manifest類型的隐式參數 implicit

      [T : ClassTag]  編譯時會自動翻譯成隐式參數和隐式值

      虛拟機運作時泛型是擦除的,不認識泛型 ,必須給具體的類型

42. 了解即可 類型限制   A < : < B  A必須是B的子類比< :更嚴格,編譯的時候就會去判斷類型

                       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層含義:

  • 子類可以實作父類的抽象方法,但不能覆寫父類的非抽象方法。
  • 子類中可以增加自己特有的方法。
  • 當子類的方法重載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更寬松。
  • 當子類的方法實作父類的抽象方法時,方法的後置條件(即方法的傳回值)要比父類更嚴格。

參考文章:

http://www.tuicool.com/articles/vaAnmq

45.this.type表示目前對象(this)的類型,this指代目前的對象。this.type被用于變量,函數參數和函數傳回值的類型聲明,主要是在某些場合下加強類型限制,或者說是為了確定類型的絕對安全,鍊式調用

46. type相當于起個别名

47.  spark很少使用 結構類型 不想從類或者接口的角度限制它, 傳入的參數包含某種方法

48. 複合類型(extend ....with ....with.... )與結構類型結合使用 

49.infix type (中置類型)  中置表達式(右結合)   :> 代表函數名   中置類型:類型名稱寫在兩個參數中間,泛型的執行個體在類型的兩側

object :> {
    def unapply[A] (list: List[A]) = {
        Some( (list.init, list.last) )
    }
}

object Extractor_Advanced {

  def main(args: Array[String]) {
    (1 to 9).toList match{ case _ :> 9 => println("Hadoop") }
    (1 to 9).toList match{ case x :> 8 :> 9 => println("Spark") }
    (1 to 9).toList match{ case :>(:>(_,8),9) => println("Flink") }
    
  }

}      

50.self type 自身類型 self => 給this執行個體指針起别名   内部類引用非常友善  this:S1 =>自身類型執行個體限制必須混入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)=>{

    }

  }

64.for循環中的模式比對

  for其實調用的是foreach

for((k,v:Int) <-List(("spark"->5),("Hadoop"->"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