目錄
一、聲明變量
val/var 變量標識:變量類型 = 初始值
- val定義的是不可重新賦值的變量
- var定義的是可重新賦值的變量
- scala中定義變量類型寫在變量名後面
- scala的語句最後不需要添加分號
二、類型推斷定義變量
scala> val name = "tom"
name: String = tom
scala可以自動根據變量的值來自動推斷變量的類型,這樣編寫代碼更加簡潔。
三、惰性賦值
當有一些變量保存的數據較大時,但是不需要馬上加載到JVM內存。可以使用惰性賦值來提高效率。
語法格式:
lazy val/var 變量名 = 表達式
四、字符串
雙引號
val/var 變量名 = "字符串"
插值表達式
插值表達式可以有效避免大量字符串的拼接。
val/var 變量名 = s"${變量/表達式}字符串"
在定義字符串之前添加s
在字符串中,可以使用${}來引用變量或者編寫表達式
使用三引號
大段的文本需要保存,可以使用三引號來定義字符串。例如:保存一大段的SQL語句。三個引號中間的所有字符串都將作爲字符串的值。
val/var 變量名 = """字符串1
字符串2"""
val sql = """select
| *
| from
| t_user
| where
| name = "zhangsan""""
println(sql)
五、數據類型與操作符
scala中的類型以及操作符絕大多數和Java一樣
數據類型
基礎類型 |
類型說明 |
Byte |
8位帶符號整數 |
Short |
16位帶符號整數 |
Int |
32位帶符號整數 |
Long |
64位帶符號整數 |
Char |
16位無符號Unicode字符 |
String |
Char類型的序列(字符串) |
Float |
32位單精度浮點數 |
Double |
64位雙精度浮點數 |
Boolean |
true或false |
注意下 scala類型與Java的區別
- scala中所有的類型都使用大寫字母開頭
- 整形使用Int而不是Integer
- scala中定義變量可以不寫類型,讓scala編譯器自動推斷
運算符
類別 |
操作符 |
算術運算符 |
+、-、*、/ |
關係運算符 |
>、<、==、!=、>=、<= |
邏輯運算符 |
&&、||、! |
- scala中沒有,++、--運算符
與Java不一樣,在scala中,可以直接使用==、!=進行比較,它們與equals方法表示一致。而比較兩個對象的引用值,使用eq
scala類型層次結構
類型 |
說明 |
Any |
所有類型的父類,,它有兩個子類AnyRef與AnyVal |
AnyVal |
所有數值類型的父類 |
AnyRef |
所有對象類型(引用類型)的父類 |
Unit |
表示空,Unit是AnyVal的子類。它類似於Java中的void,但scala要比Java更加面向對象 |
Null |
Null是AnyRef的子類,也就是說它是所有引用類型的子類。可以將null賦值給任何對象類型 |
Nothing |
所有類型的子類 不能直接創建該類型實例,某個方法拋出異常時,返回的就是Nothing類型,因爲Nothing是所有類的子類,那麼它可以賦值爲任何類型 |
六、條件表達式
條件表達式就是if表達式。scala條件表達式的語法和Java一樣。
scala> val sex = "male"
sex: String = male
scala> val result = if(sex == "male") 1 else 0
result: Int = 1
與Java不一樣的是,
- 在scala中,條件表達式也是有返回值的
- 在scala中,沒有三元表達式,可以使用if表達式替代三元表達式
塊表達式
- scala中,使用{}表示一個塊表達式
- 和if表達式一樣,塊表達式也是有值的
- 值就是最後一個表達式的值
scala> val a = {
| println("1 + 1")
| 1 + 1
| }
七、循環
在scala中,可以使用for和while,但一般推薦使用for表達式,因爲for表達式語法更簡潔
for表達式
for(i <- 表達式/數組/集合) {
// 表達式
}
簡單循環
使用for表達式打印1-10的數字
參考代碼1
scala> val nums = 1.to(10)
nums: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9,10)
scala> for(i <- nums) println(i)
參考代碼2
// 中綴調用法
scala> for(i <- 1 to 10) println(i)
嵌套循環
使用for表達式,打印以下字符
*****
*****
*****
for(i <- 1 to 3; j <- 1 to 5) {print("*");if(j == 5) println("")}
守衛
for表達式中,可以添加if判斷語句,這個if判斷就稱之爲守衛。我們可以使用守衛讓for表達式更簡潔。
for(i <- 表達式/數組/集合 if 表達式) {
// 表達式
}
示例
使用for表達式打印1-10之間能夠整除3的數字
// 添加守衛,打印能夠整除3的數字
for(i <- 1 to 10 if i % 3 == 0) println(i)
for推導式
在for循環體中,可以使用yield表達式構建出一個集合,我們把使用yield的for表達式稱之爲推導式
示例
生成一個10、20、30...100的集合
// for推導式:for表達式中以yield開始,該for表達式會構建出一個集合
val v = for(i <- 1 to 10) yield i * 10
while循環
scala中while循環和Java中是一致的
示例
打印1-10的數字
scala> var i = 1
i: Int = 1
scala> while(i <= 10) {
| println(i)
| i = i+1
| }
八、break和continue
- scala中,沒有break/continue關鍵字
- 如果一定要使用break/continue,就需要使用scala.util.control包的Break類的breable和break方法。
實現break
用法
- 導入Breaks包import scala.util.control.Breaks._
- 使用breakable將for表達式包起來
- for表達式中需要退出循環的地方,添加break()方法調用
示例
使用for表達式打印1-100的數字,如果數字到達50,退出for表達式
// 導入scala.util.control包下的Break
import scala.util.control.Breaks._
breakable{
for(i <- 1 to 100) {
if(i >= 50) break()
else println(i)
}
}
實現continue
用法
continue的實現與break類似,但有一點不同:
實現continue是用breakable{}將for表達式的循環體包含起來
示例
打印1-100的數字,使用for表達式來遍歷,如果數字能整除10,不打印
// 導入scala.util.control包下的Break
import scala.util.control.Breaks._
for(i <- 1 to 100 ) {
breakable{
if(i % 10 == 0) break()
else println(i)
}
}
九、方法
一個類可以有自己的方法,scala中的方法和Java方法類似。但scala與Java定義方法的語法是不一樣的。
定義方法
def methodName (參數名:參數類型, 參數名:參數類型) : [return type] = {
// 方法體:一系列的代碼
}
- 參數列表的參數類型不能省略
- 返回值類型可以省略,由scala編譯器自動推斷
- 返回值可以不寫return,默認就是{}塊表達式的值
示例
- 定義一個方法,實現兩個整形數值相加,返回相加後的結果
- 調用該方法
scala> def add(a:Int, b:Int) = a + b
m1: (x: Int, y: Int)Int
scala> add(1,2)
res10: Int = 3
返回值類型推斷
scala定義方法可以省略返回值,由scala自動推斷返回值類型。
定義遞歸方法,不能省略返回值類型
定義遞歸方法(求階乘)
10 * 9 * 8 * 7 * 6 * ... * 1
scala> def m2(x:Int) = {
| if(x<=1) 1
| else m2(x-1) * x
| }
<console>:13: error: recursive method m2 needs result type
else m2(x-1) * x
十、方法參數
scala中的方法參數,使用比較靈活。它支持以下幾種類型的參數:
- 默認參數
- 帶名參數
- 變長參數
默認參數
在定義方法時可以給參數定義一個默認值。
// x,y帶有默認值爲0
def add(x:Int = 0, y:Int = 0) = x + y
add()
帶名參數
在調用方法時,可以指定參數的名稱來進行調用。
def add(x:Int = 0, y:Int = 0) = x + y
add(x=1)
變長參數
如果方法的參數是不固定的,可以定義一個方法的參數是變長參數。
def 方法名(參數名:參數類型*):返回值類型 = {
方法體
}
在參數類型後面加一個*號,表示參數可以是0個或者多個
scala> def add(num:Int*) = num.sum
add: (num: Int*)Int
scala> add(1,2,3,4,5)
res1: Int = 15
十一、方法調用方式
在scala中,有以下幾種方法調用方式,
- 後綴調用法
- 中綴調用法
- 花括號調用法
- 無括號調用法
後綴調用法
這種方法與Java沒有區別。
對象名.方法名(參數)
使用後綴法Math.abs求絕對值
scala> Math.abs(-1)
res3: Int = 1
中綴調用法
語法 注意空格
對象名 方法名 參數
例如:1 to 10
如果有多個參數,使用括號括起來
示例
使用中綴法Math.abs求絕對值
scala> Math abs -1
res4: Int = 1
操作符即方法
scala中,+ - * / %等操作符都是方法,操作符是一個方法名字是符號的方法。
花括號調用法
Math.abs{
// 表達式1
// 表達式2
}
方法只有一個參數,才能使用花括號調用法
使用花括號調用法Math.abs求絕對值
scala> Math.abs{-10}
res13: Int = 10
無括號調用法
如果方法沒有參數,可以省略方法名後面的括號
- 定義一個無參數的方法,打印"hello"
- 使用無括號調用法調用該方法
參考代碼
def m3()=println("hello")
m3()
十二、函數
定義函數
val 函數變量名 = (參數名:參數類型, 參數名:參數類型....) => 函數體
- 函數是一個對象(變量)
- 類似於方法,函數也有輸入參數和返回值
- 函數定義不需要使用def定義
- 無需指定返回值類型
scala> val add = (x:Int, y:Int) => x + y
add: (Int, Int) => Int = <function2>
scala> add(1,2)
res3: Int = 3
方法和函數的區別
- 方法是隸屬於類或者對象的,在運行時,它是加載到JVM的方法區中
- 可以將函數對象賦值給一個變量,在運行時,它是加載到JVM的堆內存中
- 函數是一個對象,繼承自FunctionN,函數對象有apply,curried,toString,tupled這些方法。方法則沒有
方法無法賦值給變量
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int
scala> val a = add
<console>:12: error: missing argument list for method add
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `add _` or `add(_,_)` instead of `add`.
val a = add
方法轉換爲函數
- 有時候需要將方法轉換爲函數,作爲變量傳遞,就需要將方法轉換爲函數
- 使用_即可將方法轉換爲函數
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int
scala> val a = add _
a: (Int, Int) => Int = <function2>