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("正常結束回圈")
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555238.html
標籤:Scala
下一篇:返回列表