1. 程式人生 > >Scala學習筆記(1)

Scala學習筆記(1)

ont arr oat rim import 經歷 變參 文件 變量類型

Scala的基礎語法

1、變量類型

AnyVal

共有9種:

  Byte、Short、Int、Long、Float、Double、Char、Boolean、Unit(void)

AnyRef

  String....

2、val和var的區別

scala有兩種定義變量的方式:val和var

val定義好變量後,無法更改變量的值,類似於java中的final

var定義的變量,可以多次修改。

unit表示無值,和其他語言中的void相同。

var 變量名稱:變量類型 = 變量具體值

在不指定變量數據類型的情況下,scala會自動對其類型推導。

推薦使用val

3、循環

基本語法結構:for( 變量 <- 表達式) ,eg:for( i<- 0.until(s.length) )、for(ch <- "Hello" )

高級for循環:以變量 <- 表達式的形式提供多個生成器,用分號隔開它們,每個生成器都可以帶一個守衛:以if開頭的Boolean表達式。

for( i < 1 to 3 ;j <- 1 to 3 ) print( (10* i +j ) + " ")
//打印:11 12 13 21 22 23 31 32 33 ,每個i都會經歷j<-1 to 3

for( i < 1 to 3 ; from = 4 -i ;j <- from to 3 ) print( (10* i +j ) + " ")
//打印: 13 22 23 31 32 33 ,每個i都會經歷from = 4 -i ;每個form都會經過j <- from to 3

for( i < 1 to 3 ;j <- 1 to 3 if i != j) print( (10* i +j ) + " ") //帶守衛,註守衛沒有分號
//打印: 12 13 21 23 31 33 ,每個i都會經歷j <- 1 to 3 if i != j

4、break

scala中沒有break語句,但是Breaks對象提供了break方法。

引入Breaks包:

import scala.util.control.Breaks._
var a = 9
    breakable(
      while(true){
        println(a)
        a = a - 1
        if(a == 5) break()
      }
    )

5、yield的用法

yield 關鍵字的簡短總結:

針對每一次 for 循環的叠代, yield 會產生一個值,被循環記錄下來 (內部實現上,像是一個緩沖區).
當循環結束後, 會返回所有 yield 的值組成的集合.
返回集合的類型與被遍歷的集合類型是一致的.

val array = Array(1,2,3,4,5,6)
    val result = for(i <- array if i %2 == 0) yield i
    println(result.toBuffer)

遍歷文件:

import java.io.File

import scala.io.Source
/**
  * Created by fred on 2018/7/1.
  */
object YieldDemo{
  val files = (new File("/Users/fred/Desktop/Data/scala_test")).listFiles()

//  for(file <- files){
//    println(file)
//  }

  def fileLines(file:java.io.File) ={
    Source.fromFile(file).getLines.toList
  }

  def main(args: Array[String]): Unit = {
    val result = for{
      file <- files if file.getName.endsWith(".txt")

      line <- fileLines(file)

      trimmedLine = line.trim if trimmedLine.matches(".*scala.*")

    } yield trimmedLine.length

    result.foreach(println)

  }
}

6、方法和函數

方法:方法作用於對象,是對象的行為。

定義方法的基本格式是:def 方法名稱(參數列表):返回值 = 方法體

函數定義有兩種方式:

(1)val 函數名稱:(參數名稱:參數類型...) => 業務運算邏輯

(2)val 函數名稱:(參數類型...) => 返回值類型 = (參數) => 業務運算邏輯

scala中方法的返回值默認是方法體中的最後一行表達式 的值,當然也可以用return來執行返回值,但scala並不推薦這麽做。

scala提供一些強大的功能:類型推斷。在定義方法時,可以不顯式 的制定方法的返回值,scala編譯器可以根據函數體中的具體內容來推斷方法的返回值類型。

/*不顯示的指定返回值類型*/
  def function01(a:Int, b:Int) = {
    a + b
  }
  /*顯示的指定返回值類型*/
  def function02(a:Int, b:Int):Int = {
    a + b
  }

需要註意的是,若使用return來制定函數的返回值,次數scala的類型推斷將會失效,必須顯式執行返回值類型。

返回值類型:1)函數不是遞歸的就不需要指定返回類型,可以根據=符號右側表達推斷出來。2)如果方法使用了return,必須制定方法的返回值類型

/*不顯示的指定返回值類型
  *return時,若不指定返回值類型會編譯出錯
  * */
  def function01(a:Int, b:Int) = {
    return a + b
  }
  /*顯示的指定返回值類型*/
  def function02(a:Int, b:Int):Int = {
    return a + b
  }
/*
    遞歸
     */
    def multiply(n:Int):Int = {
      if(n == 1) 1
      else n * multiply(n - 1)
    }

當然,方法也可以沒有返回值(返回值是Unit)。

默認參數和帶名參數

在定義方法參數時,可以為某個參數指定默認值,帶有默認值的參數在被調用時可以不為其傳入實參。

def function03(left:String = "[", content:String, right:String = "]"): Unit ={
    println(left + content + right)
  }

上面定義的方法中,參數leftright已經指定默認值,可以用下面的方式進行調用

function03(content = "hello")

這裏有一點需要註意,當未被指定默認值的參數不是第一個參數時,參數名稱不能省略

 /*這樣調用是不對的*/
    function03("hello")

可變參數

當方法需要多個相同類型的參數時,可以用可變參數簡化方法的定義

def sum(args:Int*){
      var result = 0
      for(arg <- args) result += arg
      println(result)
    }

函數的定義:

/**
    * 函數的定義有兩種方式
    */
  /*匿名函數*/
  (a: Int, b: Int) => a + b

  /*方式一
  val 函數名稱:(參數名稱:參數類型...) => 業務運算邏輯
   */
  val f0 = (a: Int, b: Int) => a + b
  /*
  方式二
  val 函數名稱:(參數類型...) => 返回值類型 = (參數) => 業務運算邏輯
   */
  val f1: (Int, Int) => Int = (a, b) => a + b

參數列表:對方法是可選的,對函數是必須的(函數參數列表可以為空)。函數本身可以作為方法的參數傳入。

  def callFunc(a: Int, b: Int) = {
    f0(a, b)
  }

  def callFunc_1(a: Int, b: Int, f: (Int, Int) => Int) = {
    f(a, b)
  }

在需要函數的地方可以提供一個方法(自動轉換)

例如,高階函數接收的是一個函數,但也可以傳入一個方法,scala會將這個方法自動轉義成函數。

    def function04(x:Any) = println(x)
    val list = List[String]("a", "b", "c", "d")
    list.foreach(function04(_))

Scala學習筆記(1)