Scala學習筆記(1)
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) }
上面定義的方法中,參數left
和right
已經指定默認值,可以用下面的方式進行調用
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)