# scala的基本語法 ## 註釋 對於scala的註釋,簡而言之就是一句話,和java的註釋一模一樣 基本語法 ``` (1)單行註釋:// (2)多行註釋:/* */ (3)文檔註釋:/** * */ ``` 代碼示例: ```Scala package com.doitedu.demo01 ...
scala的基本語法
註釋
對於scala的註釋,簡而言之就是一句話,和java的註釋一模一樣
基本語法
(1)單行註釋://
(2)多行註釋:/* */
(3)文檔註釋:/**
*
*/
代碼示例:
package com.doitedu.demo01
object TestNotes {
def main(args: Array[String]): Unit = {
//(1)單行註釋://
println("濤哥")
//(2)多行註釋:/* */
/*
println("濤哥")
println("行哥")
*/
//(3)文檔註釋:
/**
*
*/
/**
* println("乃哥")
* println("雨哥")
* println("行哥")
*/
}
}
變數和常量(重點)
// 回顧:Java 變數和常量語法
// 變數類型 變數名稱 = 初始值
int a = 10
// final 常量類型 常量名稱 = 初始值
final int b = 20
scala定義變數常量的基本語法
Scala
// var 變數名 [: 變數類型] = 初始值
var i:Int = 10 variable :可變的
// val 常量名 [: 常量類型] = 初始值
val j:Int = 20 value :值
var variable 可變的 代表聲明變數
val value 值 代表聲明常量
註意:
• val 在編程的過程中我們大部分的操作是獲取值或者是獲取一個創建好的對象,然後操作對象中的屬性,很少改變這個對象變數
• val 是線程安全的 , 在使用的時候效率更高
• 優先使用val ,但是當變數後續的需要變化的時候使用var
package com.doitedu.demo02
object TestVar {
def main(args: Array[String]): Unit = {
//(1)聲明變數時,類型可以省略,編譯器自動推導,即類型推導
var age = 18
age = 30
//(2)類型確定後,就不能修改,說明 Scala 是強數據類型語言。
// age = "zhangsan" // 錯誤
//(3)變數聲明時,必須要有初始值
// var name //錯誤
//(4)在聲明/定義一個變數時,可以使用 var 或者 val 來修飾,var 修飾的變數可改變,val 修飾的變數不可改。
var num1 = 10 // 可變
val num2 = 20 // 不可變
num1 = 30 // 正確
//num2 = 100 //錯誤,因為 num2 是 val 修飾的
}
}
object demo03{
def main(args: Array[String]): Unit = {
// p1 是 var 修飾的,p1 的屬性可以變,而且 p1 本身也可以變
var p1 = new Person()
p1.name = "zhangsan"
p1 = null
// p2 是 val 修飾的,那麼 p2 本身就不可變(即 p2 的記憶體地址不能變),
但是,p2 的屬性是可以變,因為屬性並沒有用 val 修飾。
val p2 = new Person()
p2.name="jinlian"
// p2 = null // 錯誤的,因為 p2 是 val 修飾的
}
}
class Person{
var name : String = "jinlian"
}
練一練:
多易現在開售了一個小課堂來賣課(小型的電商平臺):
對於銷售這塊而言,我們是不是要存在一些屬性欄位:
店鋪名稱:多易教育
課程名稱:java基礎,mysql,hadoop.....
講課老師:源哥,濤哥,星哥,行哥
課程的價格:199,299,399,99
紅包類型: 首次購買紅包,老學員紅包
紅包金額:9.9 18.8
活動名稱:老用戶再次購買,新用戶首次購買,學員推薦購買
活動類型:6.18 10.24 11.11
活動折扣力度:9折 5折 8.8折
購買用戶用戶名:zhangsan,lisi
用戶手機號:18860875775,18860875776
用戶現在的職位:etl工程師,大數據開發工程師,數倉工程師
用戶的郵箱:email
訂單號:111122223333
訂單金額:398
代碼:
package com.doitedu
object demo01{
/**
* 店鋪名稱:多易教育
* 課程名稱:java基礎,mysql,hadoop.....
* 講課老師:源哥,濤哥,星哥,行哥
* 課程的價格:199,299,399,99
* 紅包類型: 首次購買紅包,老學員紅包
* 紅包金額:9.9 18.8
* 活動名稱:老用戶再次購買,新用戶首次購買,學員推薦購買
* 活動類型:6.18 10.24 11.11
* 活動折扣力度:9折 5折 8.8折
* 購買用戶用戶名:薑海濤,江一
* 用戶手機號:18860875775,1886087,5776
* 用戶現在的職位:etl工程師,大數據開發工程師,數倉工程師
* 用戶的郵箱:email
* 訂單號:111122223333
* 訂單金額:119.4
*/
def main(args: Array[String]): Unit = {
//店鋪名稱:多易教育
val shopName = "多易教育"
//課程名稱:java基礎,mysql,hadoop.....
val subjectName = "java基礎"
//講課老師:源哥,濤哥,星哥,行哥
val tName = "濤哥"
//課程的價格:199,299,399,99
val subjectPrice = 199.00
//紅包類型: 首次購買紅包,老學員紅包
val bonusType = "new"
//紅包金額
val bonus = 9.9
//活動名稱
val activeName = "老用戶再次購買"
//活動類型:6.18 10.24 11.11
val activeType = "程式員節"
//活動折扣力度
val activeDiscount = 0.6
//購買用戶用戶名
val userName = "haiTao Jiang"
//用戶手機號
val tel = "13372090488"
//用戶郵箱
val email = "[email protected]"
//訂單號
val orderId = "111122223333"
//訂單金額
val orderAmount = 119.4
}
}
標識符的命名規範
Scala 對各種變數、方法、函數等命名時使用的字元序列稱為標識符。即:凡是自己可
以起名字的地方都叫標識符。
命名規則:
Scala 中的標識符聲明,基本和 Java 是一致的,但是細節上會有所變化,總結後有三點:
- 以字母或者下劃線開頭,後接字母、數字、下劃線 正常情況下:字母加下劃線偶爾來個數字
- 以操作符開頭,且只包含操作符(+ - / # !等)
- 用反引號
....
包括的任意字元串,即使是 Scala 關鍵字(39 個)也可以
• package, import, class, object, trait, extends, with, type, for
• private, protected, abstract, sealed, final, implicit, lazy, override
• try, catch, finally, throw
• if, else, match, case, do, while, for, return, yield
• def, val, var
• this, super
• new
• true, false, null
練一練:
需求:判斷 hello、Hello12、1hello、h-b、x h、h_4、ab、Int、、+-/#!、+-/#!1、if、if
,這些名字是否合法。
object Test01 {
def main(args: Array[String]): Unit = {
// (1)以字母或者下劃線開頭,後接字母、數字、下劃線
var hello: String = "" // ok
var Hello12: String = "" // ok
var 1hello: String = "" // error 數字不能開頭
var h-b: String = "" // error 不能用-
var x h: String = "" // error 不能有空格
var h_4: String = "" // ok
var _ab: String = "" // ok
var Int: String = "" // ok 因為在 Scala 中 Int 是預定義的字元,不是關鍵字,但不推薦
var _: String = "hello" // ok 單獨一個下劃線不可以作為標識符,因為_被認為是一個方法println(_)
//(2)以操作符開頭,且只包含操作符(+ - * / # !等)
var +*-/#! : String = "" // ok
var +*-/#!1 : String = "" // error 以操作符開頭,必須都是操作符
//(3)用反引號`....`包括的任意字元串,即使是 Scala 關鍵字(39 個)也可以
var if : String = "" // error 不能用關鍵字
var `if` : String = "" // ok 用反引號`....`包括的任意字元串,包括關鍵字
}
}
字元串輸出
基本語法:
- 字元串,通過+號連接
- printf 用法:字元串,通過%傳值。
- 字元串模板(插值字元串):通過$獲取變數值
代碼測試:
package com.doitedu.demo04
object TestString{
def main(args: Array[String]): Unit = {
var name: String = "jinlian"
var age: Int = 18
//(1)字元串,通過+號連接
println(name + " " + age)
//可以用$來引用變數,大括弧{}可以寫也可以不寫,如果不寫,中間要用空格隔開
//最前面小寫的s就是固定寫法,寫了他相當於就是一個模板字元串,咱們可以用$去引用變數了
println(s"${name}今年${age}歲了")
//(2)printf 用法字元串,通過%傳值。 他是不換行的,如果需要換行,那麼要用\r\n來寫在末尾換行
printf("name=%s age=%d\r\n",name,age)
val price = 119.99
printf("這個商品的價格是%.2f",price)
//(3)字元串,通過$引用
//多行字元串,在 Scala中,利用三個雙引號包圍多行字元串就可以實現。
//輸入的內容,帶有空格、\t 之類,導致每一行的開始位置不能整潔對齊。
//應用 scala 的 stripMargin 方法,在 scala 中 stripMargin 預設
是“|”作為連接符,//在多行換行的行頭前面加一個“|”符號即可。
val sql =
"""
|select
|name,
|count(1) as cnt
|from
|table_a
|where name = "zhangSan"
|and age = 18
|group by name;
|""".stripMargin
println(sql )
//如果需要對變數進行運算,那麼可以加${}
val sql01 =
"""
|select
|name,
|count(1) as cnt
|from
|table_a
|where name = "$name"
|and age = ${age+2}
|group by name;
|""".stripMargin
println(sql01 )
val s2 = s"name=$name"
println(s2)
}
}
printf中格式化輸出的模板
%d 十進位數字
%s 字元串
%c 字元
%e 指數浮點數
%f 浮點數
%i 整數(十進位)
%o 八進位
%u 無符號十進位
%x 十六進位
數據類型(重點)
Java基本類型:char、byte、short、int、long、float、double、boolean
Java引用類型:(對象類型)
Java基本類型的包裝類:Character、Byte、Short、Integer、Long、Float、Double、Boolean
由於Java有基本類型,而且基本類型不是真正意義的對象,即使後面產生了基本類型的包裝類,但是仍然存在基本數據類型,所以Java語言並不是真正意思的面向對象。
• scala中的數據類型和java中數據類型最大的區別就是scala中的數據類型都是對象 , 也就是scala中沒有原生的數據類型!
• scala中的數據類型分成兩類 AnyVal(值類型)和AnyRef(引用類型) , 兩種對象都屬於Any ,都是對象
val age:Int = 23
age是一個Int數值類型的變數 , 數值類型的變數也屬於一個對象 , 所以age變數就是一個對象,也擁有很多方法
註意:Java中基本類型和引用類型沒有共同的祖先。
- Any : 所有類型的父類 , 類似於java中的Object
- AnyVal: 數值類型(簡單類型) ==-》 對應的是java中的基本數據類型
- AnyRef: 引用數據類型
- Null: 引用類型的子類,類似於java中的null ==》 寫了一個類,將null這個值封裝在了這個Null裡面
- Unit:對應Java中的void,表示方法沒有返回值 ,他的值:() ==》 因為針對這個對象,重寫了toString 方法
- Nothing: 所類型的子類,主要用在一個函數沒有明確返回值時使用,通常異常時使用,表示此處有錯
數據類型詳細表:
Unit 類型、Null 類型和 Nothing 類型
數據類型 | 描述 |
---|---|
Unit | 表示無值,和其他語言中 void 等同。用作不返回任何結果的方法的結果類型。Unit 只有一個實例值,寫成()。 |
Null | null , Null 類型只有一個實例值 null |
Nothing | Nothing 類型在 Scala 的類層級最低端;它是任何其他類型的子類型。當一個函數,我們確定沒有正常的返回值,可以用 Nothing 來指定返回類型,這樣有一個好處,就是我們可以把返回的值(異常)賦給其它的函數或者變數(相容性) |
類型轉換
當Scala 程式在進行賦值或者運算時,精度小的類型自動轉換為精度大的數值類型,這
個就是自動類型轉換(隱式轉換)。數據類型按精度(容量)大小排序為:
說明:
- 自動提升原則:有多種類型的數據混合運算時,系統首先自動將所有數據轉換成精度大的那種數據類型,然後再進行計算。
- 把精度大的數值類型賦值給精度小的數值類型時,就會報錯,反之就會進行自動類型轉換。toInt toDouble
- (byte,short)和 char 之間不會相互自動轉換。
- byte,short,char 他們三者可以計算,在計算時首先轉換為 int 類型。
測試案例:
object Test {
def main(args: Array[String]): Unit = {
//(1)自動提升原則:有多種類型的數據混合運算時,系統首先自動將所有數據轉換成精度大的那種數值類型,然後再進行計算。
var n = 1 + 2.0
println(n) // n 就是 Double
//(2)把精度大的數值類型賦值給精度小的數值類型時,就會報錯,反之就會進行自動類型轉換。
var n2 : Double= 1.0
//var n3 : Int = n2 //錯誤,原因不能把高精度的數據直接賦值和低精度。
//(3)(byte,short)和 char 之間不會相互自動轉換。
var n4 : Byte = 1
//var c1 : Char = n4 //錯誤
var n5:Int = n4
//(4)byte,short,char 他們三者可以計算,在計算時首先轉換為 int類型。
var n6 : Byte = 1
var c2 : Char = 1
// var n : Short = n6 + c2 //當 n6 + c2 結果類型就是 int
// var n7 : Short = 10 + 90 //錯誤
}
}
運算符
算術運算符
測試代碼:
object Test {
def main(args: Array[String]) {
var a = 10;
var b = 20;
var c = 25;
var d = 25;
println("a + b = " + (a + b) );
println("a - b = " + (a - b) );
println("a * b = " + (a * b) );
println("b / a = " + (b / a) );
println("b % a = " + (b % a) );
println("c % a = " + (c % a) );
}
}
關係運算符
代碼測試:
def main(args: Array[String]) {
var a = 10;
var b = 20;
println("a == b = " + (a == b) );
println("a != b = " + (a != b) );
println("a > b = " + (a > b) );
println("a < b = " + (a < b) );
println("b >= a = " + (b >= a) );
println("b <= a = " + (b <= a) );
}
邏輯運算符
代碼測試:
val a = true
val b = false
println("a && b = " + (a && b))//false
println("a || b = " + (a || b))//true
println("!(a && b) = " + !(a && b))//true
賦值運算符
註意:scala中是沒有++ -- 替換 += -=
代碼測試:
object Test {
def main(args: Array[String]): Unit = {
var r1 = 10
r1 += 1 // 沒有++
r1 -= 2 // 沒有--
}
}
位運算符
測試代碼:
object TestPosition {
def main(args: Array[String]): Unit = {
// 測試:1000 << 1 =>10000
var n1 :Int =8
n1 = n1 << 1
println(n1) //16
}
}
優先順序
流程式控制制
Scala中的流程式控制制和java基本一致
範圍數據迴圈(To)
基本語法
for(i <- 1 to 10){
println(i)
}
(1)i 表示迴圈的變數,<- 規定 to
(2)i 將會從 1-3 迴圈,前後閉合
需求:輸出 5 句 "hello world"
object TestFor {
def main(args: Array[String]): Unit = {
for(i <- 1 to 5){
println("hello world"+i)
}
}
}
範圍數據迴圈(Until)
基本語法:
for(i <- 1 until 5) {
println(i)
}
(1)這種方式和前面的區別在於 i 是從 1 到 5-1 即[0,5)
(2)即使前閉合後開的範圍
練習:
需求:用until輸出 5 句 "hello world"
Scala
object TestFor {
def main(args: Array[String]): Unit = {
for(i <- 1 until 5+1){
println("hello world"+i)
}
}
}
迴圈守衛
基本語法
for(i <- 1 to 3 if i != 2) {
println(i)
}
// 迴圈守衛,即迴圈保護式(也稱條件判斷式,守衛)。保護式為 true 則進入迴圈體內部,為 false 則跳過,類似於 continue。
// 代碼等價:
for (i <- 1 to 3){
if (i != 2) {
print(i + " ")
}
}
// 需求:輸出 1 到 5 中,不等於 3 的值
object TestFor {
def main(args: Array[String]): Unit = {
for (i <- 1 to 5 if i != 3) {
println(i + "doit")
}
}
}
迴圈步長
基本語法:
說明:by 表示步長
for (i <- 1 to 10 by 2) {
println("i=" + i)
}
// 需求:輸出 1 到 10 以內的所有奇數
for (i <- 1 to 10 by 2) {
println("i=" + i)
}
結果:
i=1
i=3
i=5
i=7
i=9
引入變數:
基本語法:
for(i <- 1 to 3; j = 4 - i) {
println("i=" + i + " j=" + j)
}
說明:
(1)for 推導式一行中有多個表達式時,所以要加 ; 來隔斷邏輯
(2)for 推導式有一個不成文的約定:當 for 推導式僅包含單一表達式時使用圓括弧,當包含多個表達式時,一般每行一個表達式,並用花括弧代替圓括弧,如下
舉例:
for {
i <- 1 to 3
j = 4 - i
} {
println("i=" + i + " j=" + j)
}
// 等價得代碼:
Scala
for (i <- 1 to 3) {
var j = 4 - i
println("i=" + i + " j=" + j)
}
迴圈返回值
基本語法:
val res = for(i <- 1 to 10) yield i
println(res)
// 說明:將遍歷過程中處理的結果返回到一個新 Vector 集合中,使用 yield 關鍵字。
// 練習:需求:將原數據中所有值乘以 2,並把數據返回到一個新的集合中。
object TestFor {
def main(args: Array[String]): Unit = {
var res = for(i <-1 to 10) yield {
i * 2
}
println(res)
}
}
輸出結果:
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
倒序列印
說明:如果想倒序列印一組數據,可以用 reverse。
需求:倒序列印 10 到 1
for(i <- 1 to 10 reverse){
println(i)
}
迴圈中斷
基本說明:
Scala 內置控制結構特地去掉了 break 和 continue,是為了更好的適應函數式編程,推薦使用函數式的風格解決break和continue的功能,而不是一個關鍵字。Scala中使用breakable控制結構來實現 break 和 continue 功能。
方式 1:採用異常的方式退出迴圈
object Demo_while {
def main(args: Array[String]): Unit = {
try {
for (emel <- 1 to 10) {
println(emel)
if (emel == 5) {
throw new RuntimeException
}
}
} catch {
case e: Exception =>
}
println("hello")
}
}
方式 2:採用 Scala 自帶的函數,退出迴圈
import scala.util.control.Breaks
object Demo_while {
def main(args: Array[String]): Unit = {
Breaks.breakable(
for (emel <- 1 to 10) {
println(emel)
if (emel == 5) {
Breaks.break()
}
}
)
println("正常結束迴圈")
}
}
對breaks進行省略
object Demo_while {
def main(args: Array[String]): Unit = {
breakable(
for (emel <- 1 to 10) {
println(emel)
if (emel == 5) {
break()
}
}
)
println("正常結束迴圈")
}
}