動態

詳情 返回 返回

Scala基本語法 - 動態 詳情

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 = "34650965@qq.com"
    //訂單號
    val orderId = "111122223333"
    //訂單金額
    val orderAmount = 119.4
  }

}

標識符的命名規範

Scala 對各種變量、方法、函數等命名時使用的字符序列稱為標識符。即:凡是自己可
以起名字的地方都叫標識符。
命名規則:
Scala 中的標識符聲明,基本和 Java 是一致的,但是細節上會有所變化,總結後有三點:

  1. 以字母或者下劃線開頭,後接字母、數字、下劃線 正常情況下:字母加下劃線偶爾來個數字
  2. 以操作符開頭,且只包含操作符(+ - / # !等)
  3. 用反引號....包括的任意字符串,即使是 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 用反引號`....`包括的任意字符串,包括關鍵字
 } 
}

字符串輸出

基本語法:

  1. 字符串,通過+號連接
  2. printf 用法:字符串,通過%傳值。
  3. 字符串模板(插值字符串):通過$獲取變量值

代碼測試:

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中基本類型和引用類型沒有共同的祖先。
image

  1. Any : 所有類型的父類 , 類似於java中的Object
  2. AnyVal: 數值類型(簡單類型) ==-》 對應的是java中的基本數據類型
  3. AnyRef: 引用數據類型
  4. Null: 引用類型的子類,類似於java中的null ==》 寫了一個類,將null這個值封裝在了這個Null裏面
  5. Unit:對應Java中的void,表示方法沒有返回值 ,他的值:() ==》 因為針對這個對象,重寫了toString 方法
  6. Nothing: 所類型的子類,主要用在一個函數沒有明確返回值時使用,通常異常時使用,表示此處有錯

數據類型詳細表:
image
Unit 類型、Null 類型和 Nothing 類型

數據類型 描述
Unit 表示無值,和其他語言中 void 等同。用作不返回任何結果的方法的結果類型。Unit 只有一個實例值,寫成()。
Null null , Null 類型只有一個實例值 null
Nothing Nothing 類型在 Scala 的類層級最低端;它是任何其他類型的子類型。當一個函數,我們確定沒有正常的返回值,可以用 Nothing 來指定返回類型,這樣有一個好處,就是我們可以把返回的值(異常)賦給其它的函數或者變量(兼容性)

類型轉換

當Scala 程序在進行賦值或者運算時,精度小的類型自動轉換為精度大的數值類型,這
個就是自動類型轉換(隱式轉換)。數據類型按精度(容量)大小排序為:

image
説明:

  1. 自動提升原則:有多種類型的數據混合運算時,系統首先自動將所有數據轉換成精度大的那種數據類型,然後再進行計算。
  2. 把精度大的數值類型賦值給精度小的數值類型時,就會報錯,反之就會進行自動類型轉換。toInt toDouble
  3. (byte,short)和 char 之間不會相互自動轉換。
  4. 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 //錯誤
 } 
}

運算符

算術運算符

image
測試代碼:

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) );
  }
}

關係運算符

image

代碼測試:

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) );
}

邏輯運算符

image
代碼測試:

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中是沒有++ -- 替換 += -=
image

代碼測試:

object Test {
 def main(args: Array[String]): Unit = {
 var r1 = 10
 r1 += 1 // 沒有++
 r1 -= 2 // 沒有--
 }
}

位運算符

image

測試代碼:

object TestPosition {
 def main(args: Array[String]): Unit = {
 // 測試:1000 << 1 =>10000
 var n1 :Int =8
 n1 = n1 << 1
 println(n1)  //16 
 } 
} 

優先級

image

流程控制

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("正常結束循環")
  }
}
user avatar aiwandeyangrouchuan 頭像 POCOPOCOPOCO 頭像
點贊 2 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.