1. 程式人生 > >Scala基於JVM的程式語言

Scala基於JVM的程式語言

一、Scala簡介

Scala是將面向物件面向函式式整合在一起,基於JVM的程式語言。它由Martin Odersk於2001開發,2004年開始執行在JVM與.Net平臺之上,由於其簡潔、優雅、型別安全的程式設計模式而受到關注。

Scala六個特徵:

  1. Java和scala可以無縫混編(因為都是基於JVM的程式語言)
  2. 型別推測(自動推測型別)
  3. 併發和分散式(Actor)
  4. 特質trait,特徵(整合java中介面和抽象類的優點)
  5. 模式匹配(類似於java中的switch)
  6. 高階函式(函式的引數是引數,函式的返回是函式)

二、Scala基礎

1、資料型別:

Byte、Short、Int、Long、Float、Double、Char、String、Boolean。這些跟JAVA中等同。

  • Unit:表示無值,和java中的void等同
  • Null:空值或空引用
  • Nothing:其他型別的子類,表示沒有值
  • Any:所有型別的超類,任何例項都屬於Any型別,類似於JAVA中的Object
  • AnyRef:所有引用型別的超類
  • AnyVal:所有值型別的超類
    資料型別

2、變數和常量的宣告

變數:用var定義,可修改
常量:用val定義,不可修改
當引數沒有修飾,那麼外部無法通過物件來呼叫,類似於JAVA中的private。

var name = "zhangsan"
    val gender = "男"

3、類和物件

伴生類:

class Person{
  val name = "zhangsan"
  val age = 18
  def sayName() = {
    "my name is "+ name
  }
}

伴生物件:

object Lesson_Class {
   def main(args: Array[String]): Unit = {
    val person = new Person()
    println(person.age);
    println(person.sayName())
  }
}

總結:

  1. 建構函式和JAVA不一樣,直接類名後加引數
  2. 伴生類中主要宣告動態屬性,伴生物件主要宣告靜態屬性

4、if else判斷體

  • if else
  • if else if else

5、迴圈體

for迴圈

  1. 通過索引
  2. 增強for迴圈
  3. 雙重迴圈
  4. 帶有判斷條件
  5. yield

while迴圈

do while迴圈

總結:

  1. yied關鍵詞能夠將符合要求的元素自動封裝到一個集合中
  2. 1 to 10包括10,1 until 10不包括10
  3. scala中不能使用count++,只能使用count = count+1
  4. 在scala中沒有break跳出迴圈,可設定標記,例如var flag = true

6、函式

1.普通函式(有參函式、無參函式)

def fun (a: Int , b: Int ) : Unit = {
   println(a+b)
 }
fun(1,1)
    
def fun1 (a : Int , b : Int)= a+b
    println(fun1(1,2))  

2.遞迴函式:在函式體內呼叫自己本身

// 計算num的階乘
def fun1(num:Int):Int = {
    if(num == 1||num == 0) 1
    else num * fun1(num - 1)
}

3.預設值的函式

 def fun2(num1:Int = 10,num2:Int = 20) = {
    num1 + num2
}
  
  def fun3(num1:Int,num2:Int = 20) = {
    num1 + num2
}
  
  def fun4(num1:Int=10,num2:Int) = {
    num1 + num2
}

4.可變引數個數的函式

def fun4(elements :Int*)={
      var sum = 0;
      for(elem <- elements){
        sum += elem
      }
      sum
}
    println(fun4(1,2,3,4))

5.匿名函式

var fun6 = (num1:Int,num2:Int) => num1+ num2

6.巢狀函式

 def fun7(num:Int)={
      def fun8(a:Int,b:Int):Int={
        if(a == 1){
          b
        }else{
          fun8(a-1,a*b)
        }
      }
      fun8(num,1)
}

7.偏應用函式

偏應用函式是一種表示式,不需要提供函式需要的所有引數,只需要提供部分,或不提供所需引數。

  def log(date:Date,content:String) = {
    println("date:" + date + "\tcontent:" + content)
  }
  
  val date = new Date()
  log(date,"log1")
  log(date,"log2")
  log(date,"log3")
  println("==============================")
    
  val logBoundDate = log(date,_:String)
  logBoundDate("log11")
  logBoundDate("log12")
  logBoundDate("log13")

8.高階函式

函式的引數是函式,或者函式的返回型別是函式,或者函式的引數和函式的返回型別都是函式的函式。

  /**
   * 函式的引數是函式:
   * f1:(Int)=>Int  告訴要傳入的函式的格式 
   * 把函式當成了物件穿來穿去、scala支援面向函式程式設計
   */
  def highFun1(f1:(Int)=>Int,num:Int) = {
    f1(num)
  }
  
  def tmpFun(num1:Int) = {
    num1+1000
  }
  
  /**
   * 函式的返回是函式
   * 函式無引數
   * 函式的返回個(Int,Int)=>Double格式的函式
   */
  def highFun2():(Int,Int)=>Double = {
    def tmpFun2(num1:Int,num2:Int):Double = {
      num1 + num2
    }
    tmpFun2
  }
  
  def highFun3():(Int,Int)=>Double = {
    (num1:Int,num2:Int)=>num1+num2
  }
  
   /**
    * 函式是引數是函式,返回也是函式
    * 這個函式也是高階函式
    */
  def highFun4(f1:(Int,Int) => Int,num1:Int):(Int)=>Double = {
    val rest = f1(num1,1000)
    (num:Int) => num + 1
  }
  
  def highFun5(num:Int):(Int)=>Int = {
    def fun(a:Int)={
      num + a
    }
    fun
  }

9. 柯里化函式

可理解為對高階函式的簡化

def klhFun(a:Int)(b:Int) = a*b

Scala語言的簡寫規則:

  1. 函式的返回值型別可以省略,因為scala具備自動推測的功能,他會根據返回值的自動來決定這個函式的返回值型別
  2. 將你要返回的值放在函式的最後一行,那麼這個值就會被自動返回
  3. 如果你的函式體內只有一個語句,可以將這行語句與函式名在一行。

總結:

  1. 對於遞迴函式 必須明確返回值型別,不然不知所措;
  2. 預設值的函式中,如果傳入的引數個數與函式定義相同,則傳入的數值會覆蓋預設值;如果不想覆蓋預設值,傳入的引數個數小於定義的函式的引數,則需要指定引數名稱;
  3. 在scala中+=前後的數值型別必須一致,+前後的數值型別可以不一致;
  4. 注意點:
    1)匿名函式不能顯示的宣告返回值型別
    2)匿名函式必須賦給一個變數、變數,通過變數來呼叫這個匿名函式
    3)匿名函式的引數與函式體必須要用=>來關聯

7、集合

1.Array

   /**
     * 建立陣列的兩種方式:
     * 1.new Array[String](3)
     * 2.直接Array
     */   
    //建立型別為Int 長度為3的陣列
    val arr1 = new Array[Int](3)
    //建立String 型別的陣列,直接賦值
    val arr2 = Array[String]("s100","s200","s300")
    //賦值
    arr1(0) = 100
    arr1(1) = 200
    arr1(2) = 300
   /**
     * 建立二維陣列 
     */
    val secArray = new Array[Array[String]](10)
    for(index <- 0 until secArray.length){
      secArray(index) = new Array[String](10)
    }
    
   /**
     * 遍歷陣列的兩種方式
     */
    for(i <- arr1){
    	  println(i)
    }
    arr1.foreach(i => {
      println(i)
    })
    
    for(s <- arr2){
      println(s)
    }
    arr2.foreach { 
      x => println(x) 
    }

2.List

    //建立List 不可變List
    val list = List(1,2,3,4,5)
    
    //遍歷List
    list.foreach { x => println(x)}
    // list.foreach { println}
   
    // filter方法
    val list1  = list.filter { x => x>3 }
    list1.foreach { println}
    
    // count方法
    val value = list1.count { x => x>3 }
    println(value)
    
    // map
    val nameList = List(
    		"hello bjsxt",
    		"hello xasxt",
    		"hello shsxt"
        )
    val mapResult:List[Array[String]] = nameList.map{ x => x.split(" ") }
    mapResult.foreach{println}    
    
    // flatmap 先map再flat
    val flatMapResult : List[String] = nameList.flatMap{ x => x.split(" ") }
    flatMapResult.foreach { println }

   /**
     * 可變的list集合
     */
    val listBuffer = new ListBuffer[String]
    listBuffer.+=("hello")
    listBuffer.+=("bj")
    listBuffer.foreach { println }
    
    listBuffer.-=("hello")

3.Set

    //建立Set
    val set1 = Set(1,2,3,4,4)
    val set2 = Set(1,2,5)
    //遍歷Set集合
    //注意:set會自動去重
    set1.foreach { println}
   for(s <- set1){
      println(s)
    }

4.Map

 val map = Map(
                 "1" -> "bj",
                  2 -> "sh",
                  3 -> "gz"
                )
    val keys = map.keys
    val keyIterator = keys.iterator
    while(keyIterator.hasNext){
    val key = keyIterator.next()
    /**
      * map集合的get方法返回值是一個Option型別的物件
      * Option型別有兩個子型別  分別為some None
      */
      println(key + "\t" + map.get(key).get)
    }
     
     /**
      * getOrElse原理:去集合中去取資料,若不存在返回預設值
      */
     println(map.get(4).getOrElse("default"))
    
     // Map遍歷
     for(k <- map)
     println(k._1 + "\t" + k._2)
       
     map.foreach(x=>println(x._1 + "\t" + x._2))        
   
     // filter:過濾,留下符合條件的記錄
     map.filter(x=>{
       Integer.parseInt(x._1 + "") >= 2
     }).foreach(println)
     
     // count:統計符合條件的記錄數
     val count = map.count(x=>{
       Integer.parseInt(x._1 + "") >= 2
     })
     println(count)

5.Tuple

    /**
      * 元組 vs list
      * list建立的時候指定了泛型,那麼集合中必須是這個泛型的物件
      * 元祖中可以包含任意型別的元素,這些元素使用一對小括號來封裝
      * 元組的建立:最多支援22個
      */
     val t2 = Tuple2(1,"hello")
     val tt2 = (1,"hello")
     
     val t3 = Tuple3(1,true,"hello")
     val tt3 = (1,true,"hello")
     
     val moreTuple = (1,2,3)   
     
     // 元組的遍歷
     val tupleIterator = tt3.productIterator
     while(tupleIterator.hasNext){
     println(tupleIterator.next())
     }
     
     // toString方法
     println(tt3.toString())
     
     //swap交換 注意只有二元組物件才會有這個方法
     val swapt2 = tt2.swap
     println(swapt2._1 + "\t" + swapt2._2)

8、字串

    // String不可變
    val str1 = "hello bi"
    val str2 = "hello sh"
    val flag = str1.equalsIgnoreCase(str2)    
    println(flag)
    
    str1.split(" ")
    
    // StringBuffer可變
    val strBuilder = new StringBuilder
    strBuilder.append("hello\t")
    strBuilder.append("bj")
    println(strBuilder)

總結:

9、Trait特性

Scala相當於JAVA中的介面但是他比介面功能更加強大,與介面不同的是它還可以定義屬性和方法的實現。
Trait可以繼承多個Trait,也就是多繼承,Trait定義的方式與類相似,使用關鍵字trait。

10、模式匹配

11、樣例類

12、Actor