第2章 Scala變量

2.1 爲什麼需要變量

一個程序就是一個世界,在scala中一切都是對象

2.2 變量是程序的基本組成單位

不論是使用哪種高級程序語言編寫程序,變量都是其程序的基本組成單位,比如:

object ScalaFunDemo01 {

  def main(args: Array[String]): Unit = {
    var a: Int = 1 //定義一個整型變量,取名a,並賦初值1
    var b: Int = 3 //定義一個整型變量,取名b,並賦初值3
    b = 89 //給變量b 賦 89
    println("a=" + a) //輸出語句,把變量a的值輸出
    println("b=" + b) //把變量b的值輸出
  }
}

2.3 變量的介紹

2.3.1 概念

變量相當於內存中一個數據存儲空間的表示,你可以把變量看做是一個房間的門牌號,通過門牌號我們可以找到房間,而通過變量名可以訪問到變量(值)。

2.3.2 變量使用的基本步驟

① 聲明/定義變量 (scala要求變量聲明時初始化)

② 使用

2.4 變量基本使用

2.4.1 Scala變量使用案例入門

object ScalaFunDemo01 {

  def main(args: Array[String]): Unit = {

    //1.聲明變量【告訴計算機要開一個房間,並賦值】
    var num: Int = 0
    var score: Double = 1.0
    var gender: Char = 'N'
    var name: String = "scott"
    //2.賦值【可以修改值】
    num = 99
    score = 1.5
    gender = '\n' //換行..
    name = "wertyuhijfgdsfgh@#$%^&*"
    //3.使用【將值拿出來用】
    println("num=" + num)
    println("score=" + score)
    println("gender=" + gender)
    println("name=" + name)
  }
}

2.4.2 Scala變量內存

 

2.5 Scala變量使用說明

2.5.1 變量聲明基本語法

var | val 變量名 [: 變量類型] = 變量值

2.5.2 注意事項

① 聲明變量時,類型可以省略(編譯器自動推導,即類型推導)

② 類型確定後,就不能修改,說明Scala 是強數據類型語言

object ScalaFunDemo01 {

  def main(args: Array[String]): Unit = {

    var name = "jack"
    // name = 10  錯誤 name的類型被編譯器確定了,那麼 就不能改變
    name = "999"
    println("name=" + name)
  }
}

③ 在聲明/定義一個變量時,可以使用var 或者 val 來修飾, var 修飾的變量可變,val 修飾的變量不可變

object ScalaFunDemo01 {

  def main(args: Array[String]): Unit = {

    var name = "jack"
    // name = 10  錯誤 name的類型被編譯器確定了,那麼就不能改變
    name = "999"

    val name2 = "tom"
    // name2 = "scott"  錯誤,因爲name2 使用了val , 等效於final 性質
    println("name=" + name)
    println("name2=" + name2)
  }
}

var 和 val 的詳解

var 修飾的變量可變,val 修飾的變量不可變

var 修飾的對象引用可以改變,val 修飾的則不可改變,但對象的狀態(值)卻是可以改變的

val 的好處是

【1】如果一個對象不想改變其內部的狀態,那麼由於不變性,我們不用擔心程序的其他部分會改變對象的狀態

【2】 線程安全

object VarDemo01 {
  def main(args: Array[String]): Unit = {

    var name = "jack"
    name = "jack2" // ok
    val name2 = "tom"
    //name2 = "martin" // 錯誤

    //對象
    var cat = new Cat()
    cat.name = "haha" //該屬性值ok
    cat = null //該對象引用ok
    val cat2 = new Cat()
    cat2.name = "xb" //該屬性值ok
    //cat2 = null //該對象引用error
  }
}

class Cat {
  var name: String = "xh"
}

④ val修飾的變量在編譯後,等同於加上final, 通過反編譯看下底層代碼

object ScalaFunDemo01 {

  var num1 = 10
  val num2 = 20

  def main(args: Array[String]): Unit = {

    num1 = 200
    // num2 = 30 因爲num2是 val 修飾,因此是final性質的不能改.
    println("name1=" + num1)
    println("name=" + num2)
  }
}

⑤ var 修飾的對象引用可以改變,val 修飾的則不可改變,但對象的狀態(值)卻是可以改變的。(比如: 自定義對象、數組、集合等等)

class Dog {
  var age = 100
}

object Hello01 {
  def main(args: Array[String]): Unit = {

    val name = "ok"
    //name = “ok2” //錯誤name 是不能改變的.name是基本類型
    val dog = new Dog()
    println("dog.age=" + dog.age)
    dog.age = 200
    println("dog.age=" + dog.age)

    //dog = new Dog()  //錯誤,這樣相當於是重新分配內存空間,創建新的dog,從而造成地址變化
  }
}

⑥ 變量聲明時,需要初始值。

object Hello01 {
  def main(args: Array[String]): Unit = {

    val b : Int // 錯誤,沒有給初始值
    println(b)
    
  }
}

2.6 程序中 +號的使用

當左右兩邊都是數值型時,則做加法運算

當左右兩邊有一方爲字符串,則做拼接運算

object ScalaFunDemo01 {
  
  def main(args: Array[String]): Unit = {

    var name: String = "kristina"
    var score = 89.9
    println(name + " 成績是 " + score) //字符串拼接
    println(10 + score) // + 法 
    println("10" + score) // 拼接
  }
}

運行結果:

kristina 成績是 89.9

99.9

1089.9

2.7 數據類型

2.7.1 scala數據類型介紹

① Scala 與 Java有着相同的數據類型,在Scala中數據類型都是對象,也就是說scala沒有java中的原生類型

Scala語言是完全面向對象的語言,所以並不區分基本類型和引用類型,這些類型都是對象,我們稱之爲常用類型。

Scala常用類型中包含有7種數值類型:Byte、Char、Short、Int、Long、Float、Double及Boolean類型,還有String類型

所以並不區分基本類型和引用類型,這些類型都是對象 , 憑什麼這樣說呢,因爲只有你使用基本數類型(比如 Int , Float ,Double 等等),只要使用,在底層都會轉出對應的包裝類,比如

Char => Charater Int => Integer Float=>Float 等等..

② Scala數據類型分爲兩大類 AnyVal(值類型) 和 AnyRef(引用類型), 注意:不管是AnyVal還是AnyRef 都是對象。

object VarDemo01 {
  def main(args: Array[String]): Unit = {

    var num1: Int = 10
    println("num1" + num1)
    var char1: Char = 'a'
    println("char1的code= " + char1.toInt)
  }
}

class Cat {
  var name: String = "xh"
}

③ 相對於java的類型系統,scala要複雜些!也正是這複雜多變的類型系統才讓面向對象編程和函數式編程完美的融合在了一起

2.7.2 scala數據類型體系一覽圖

 

1.Scala中,所有的值都是對象,而所有的類,包括值類型,都最終繼承自一個統一的根類型Any。

2.統一類型,是Scala的又一大特點。

3.更特別的是,Scala中還定義了幾個底層類(Bottom Class),比如Null和Nothing

4.Null是所有引用類型的子類型

5.Nothing,可以作爲沒有正常返回值的方法的返回類型,非常直觀的告訴你這個方法不會正常返回,而且由於Nothing是其他任意類型的子類,他還能跟要求返回值的方法兼容

2.7.3 scala數據類型列表

數據類型

描述

Byte

8位有符號補碼整數。數值區間爲 -128 到 127

Short

16位有符號補碼整數。數值區間爲 -32768 到 32767

Int

32位有符號補碼整數。數值區間爲 -2147483648 到 2147483647

Long

64位有符號補碼整數。數值區間爲 -9223372036854775808 到 9223372036854775807

Float

32 位, IEEE 754標準的單精度浮點數

Double

64 位 IEEE 754標準的雙精度浮點數

Char

16位無符號Unicode字符, 區間值爲 U+0000 到 U+FFFF

String

字符序列

Boolean

true或false

Unit

表示無值,和其他語言中void等同。用作不返回任何結果的方法的結果類型。Unit只有一個實例值,寫成()。

Null

null

Nothing

Nothing類型在Scala的類層級的最低端;它是任何其他類型的子類型。

Any

Any是所有其他類的超類

AnyRef

AnyRef類是Scala裏所有引用類(reference class)的基類

2.8 整數類型

2.8.1 基本介紹

Scala的整數類型就是用於存放整數值的,比如 12 , 30, 3456等等

2.8.2 整型的類型

數據類型

描述

Byte [1]

8位有符號補碼整數。數值區間爲 -128 到 127

Short [2]

16位有符號補碼整數。數值區間爲 -32768 到 32767

Int [4]

32位有符號補碼整數。數值區間爲 -2147483648 到 2147483647

Long [8]

64位有符號補碼整數。數值區間爲 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1

2.8.3 整型的使用細節

① Scala各整數類型有固定的表數範圍和字段長度,不受具體OS的影響,以保證Scala程序的可移植性

② Scala的整型 常量/字面量 默認爲 Int 型,聲明Long型 常量/字面量 須後加‘l’’或‘L’

③ Scala程序中變量常聲明爲Int型,除非不足以表示大數,才使用Long

object Hello01 {
  def main(args: Array[String]): Unit = {

    var c = 11 // c 就是Int類型
    println("c=" + c)
    var d = 12l // d 就是 Long 類型 或者 var d = 12L
    println("d=" + d)

    // var e = 9223372036854775807 // 這樣直接報錯了,integer number is out of range for type int
    //解決方法,下面均可.
    var e: Long = 9223372036854775807l
    var f = 9223372036854775807l
  }
}

2.9 浮點類型

2.9.1 基本介紹

Scala的浮點類型可以表示一個小數,比如 123.4f,7.8 ,0.12等等

2.9.2 浮點型的分類

Float [4]

32 位, IEEE 754標準的單精度浮點數

Double [8]

64 位 IEEE 754標準的雙精度浮點數

2.9.3 浮點型使用細節

① 與整數類型類似,Scala 浮點類型也有固定的表數範圍和字段長度,不受具體OS的影響。

② Scala的浮點型常量默認爲Double型,聲明Float型常量,須後加‘f’或‘F’。

object Hello01 {
  def main(args: Array[String]): Unit = {

    //var f : Float = 4.5 //報錯
    //上面錯誤的解決思路
    var f: Double = 4.5
    var f2 = 4.6 //自動推導 f2 的類型爲Double
    var f3: Float = 4.5f // 4.5F 也可以
    println(" f= " + f + " f2= " + f2 + " f3= " + f3)
  }
}

③ 浮點型常量有兩種表示形式

十進制數形式:如:5.12 512.0f .512 (必須有小數點)

科學計數法形式:如:5.12e2 = 5.12乘以10的2次方 5.12E-2 = 5.12除以10的2次方

object Hello01 {
  def main(args: Array[String]): Unit = {

    var f = 512.0f // f 爲Float 類型
    var f2 = .512 // f2 爲Double 類型

    var f3 = 5.12e2 // f 爲Double 類型
    var f4 = 5.12E-2 // f2 爲Double 類型
    println("f=" + f + " f2= " + f2 + " f3= " + f3 + " f4= " + f4)

  }
}

④ 通常情況下,應該使用Double型,因爲它比Float型更精確(小數點後大致7位) //測試數據 :2.2345678912f , 2.2345678912

object Hello01 {
  def main(args: Array[String]): Unit = {

    var n1: Float = 2.2345678912f
    var n2: Double = 2.2345678912
    println("n1=" + n1 + " n2= " + n2)

  }
}

2.10 字符類型

2.10.1 基本介紹

字符類型可以表示單個字符,字符類型是Char, 16位無符號Unicode字符(2個字節), 區間值爲 U+0000 到 U+FFFF

2.10.2 字符類型使用細節

① 字符常量是用單引號('')括起來的單個字符。例如:var c1 = 'a' var c2 = '中' var c3 = '9'

② Scala 也允許使用轉義字符'\'來將其後的字符轉變爲特殊字符型常量。例如:var c3 = '\n' // '\n'表示換行符

object Hello01 {
  def main(args: Array[String]): Unit = {

    var c1: Char = '\\' //反斜線
    var c3: Char = '\'' //單引號
    var c4: Char = '\"' //雙引號
    var c2: Char = '\t' //製表符
    var c5: Char = '\r' //回車符
    var c6: Char = '\n' //換行符
    var c7: Char = '\b' //退格符
    
  }
}

③ 可以直接給Char賦一個整數,然後輸出時,會按照對應的unicode 字符輸出 ['\u0061' 97]

④ Char類型是可以進行運算的,相當於一個整數,因爲它都對應有Unicode碼.

object Hello01 {
  def main(args: Array[String]): Unit = {

    var c1: Char = 'a'
    var num: Int = 10 + c1 + 'b'

    //Expression of type Int doesn't conform to expected type Char
    //var c2 : Char =  'a' + 1 //錯誤, 這一點和java不一樣

    println(c1)
    println(num)
    // println(c2)
  }
}

2.10.3 字符類型本質探討

① 字符型 存儲到計算機中,需要將字符對應的碼值(整數)找出來

存儲:字符——>碼值——>二進制——>存儲

讀取:二進制——>碼值——> 字符——>讀取

②字符和碼值的對應關係是通過字符編碼表決定的(是規定好), 這一點和Java一樣。

object Hello01 {
  def main(args: Array[String]): Unit = {
    
    var c3: Char = '國'
    println("c3=" + c3 + "c3對應的碼值=" + c3.toInt)
    var c4: Char = 22269 //直接給c4一個碼值,默認輸出對應的字符
    println("c4=" + c4)

  }
}

打印結果:

c3=國c3對應的碼值=22269

c4=國

2.11 布爾類型

2.11.1 基本介紹

① 布爾類型也叫Boolean類型,Booolean類型數據只允許取值true和false

② boolean類型佔1個字節。

③ boolean 類型適於邏輯運算,一般用於程序流程控制:

if條件控制語句

while循環控制語句

do-while循環控制語句

for循環控制語句

object Hello01 {
  def main(args: Array[String]): Unit = {
    var b: Boolean = true
    println(b)
    
    //錯誤,Boolean 不能使用接收數字和null    
    //只能接收true或者false
    var b2 : Boolean = 0
    var b3 : Boolean = null //錯, 運行就會報錯.
    println(b3)
  }
}

2.12 Unit類型、Null類型和Nothing類型

2.12.1 基本說明

Unit

表示無值,和其他語言中void等同。用作不返回任何結果的方法的結果類型。Unit只有一個實例值,寫成()。

Null

null , Null 類型只有一個實例值 null

Nothing

Nothing類型在Scala的類層級的最低端;它是任何其他類型的子類型。

當一個函數,我們確定沒有正常的返回值,可以用Nothing 來指定返回類型,這樣有一個好處,就是我們可以把返回的值(異常)賦給其它的函數或者變量(兼容性)

2.12.2 使用細節和注意事項

① Null類只有一個實例對象null,類似於Java中的null引用。null可以賦值給任意引用類型(AnyRef),但是不能賦值給值類型(AnyVal: 比如 Int, Float, Char, Boolean, Long, Double, Byte, Short)

class Dog {

}

object Hello01 {
  def main(args: Array[String]): Unit = {

    var dog: Dog = null // dog 是引用類型
    var n1: Char = null //錯誤 [Int , Double 等等都不可以]

  }
}

② Unit類型用來標識過程,也就是沒有明確返回值的函數。由此可見,Unit類似於Java裏的void。Unit只有一個實例,(),這個實例也沒有實質的意義

object Hello01 {
  def main(args: Array[String]): Unit = {

    var res = sayOk()
    println("res=" + res)
  }

  def sayOk(): Unit = { //Unit 表示沒有返回值
    println("sayok被調用")
  }
}

打印結果:

sayok被調用

res=()

③ Nothing,可以作爲沒有正常返回值的方法的返回類型,非常直觀的告訴你這個方法不會正常返回,而且由於Nothing是其他任意類型的子類,他還能跟要求返回值的方法兼容。

2.13 值類型轉換

2.13.1 值類型隱式轉換

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

② 數據類型按精度(容量)大小排序爲

 

2.13.2 高級隱式轉換和隱式函數

scala還提供了非常強大的隱式轉換機制(隱式函數,隱式類等等),在高級部分專門來說

2.13.3 強制類型轉換

自動類型轉換的逆過程,將容量大的數據類型轉換爲容量小的數據類型。使用時要加上強制轉函數,但可能造成精度降低或溢出,格外要注意。

java : int num = (int)2.5

scala : var num : Int = 2.7.toInt //對象

強制類型轉換細節說明

① 當進行數據的 從 大——>小,就需要使用到強制轉換

② 強轉符號只針對於最近的操作數有效,往往會使用小括號提升優先級

int y = (int)(10*3.5+6*1.5)

③ Char類型可以保存 Int的常量值,但不能保存Int的變量值,需要強轉

char c1 = 100 //ok
int m = 100 //ok
char c2 = m //錯誤
char c2 = (char)m //ok
char c3 = 'a'
char c4 = (char)(c3+2) //因爲 int 和 char  不會發生自動轉換,因此需要強制轉換

④ Byte和Short類型在進行運算時,當做Int類型處理。

byte b = 12
short s = 20
//short s2 = b+s 這個是錯誤的,因爲b+s後是int類型。
short s2 = (short)(b+s) // 強制轉換ok

2.14 值類型和String類型的轉換

2.14.1 介紹

在程序開發中,我們經常需要將基本數據類型轉成String 類型。

或者將String類型轉成基本數據類型。

2.14.2 基本類型轉String類型

語法: 將基本類型的值+"" 即可

String str1 = true + ""
String str2 = 2 + ""
String str3 = 3.14 + ""

2.14.3 String類型轉基本數據類型

語法:通過基本類型的String的 toXxx方法即可

object VarDemo01 {
  def main(args: Array[String]): Unit = {
    //說明如果給的s1 不能轉成對應類型就會拋出異常.可以利用這個機制做業務處理
    var s1: String = "12"
    var n1 = s1.toInt
    var n2 = s1.toFloat
    var n3 = s1.toDouble
    var n4 = s1.toByte
    var n5 = s1.toLong
    var n6 = s1.toShort
    println(n1 + " " + n2 + " " + n3)
  }
}

2.14.4 注意事項

在將String 類型轉成 基本數據類型時,要確保String類型能夠轉成有效的數據,比如 我們可以把 "123" , 轉成一個整數,但是不能把 "hello" 轉成一個整數

2.15 標識符的命名規範

2.15.1 標識符概念

① Scala 對各種變量、方法、函數等命名時使用的字符序列稱爲標識符

② 凡是自己可以起名字的地方都叫標識符

2.15.2 標識符的命名規則

Scala中的標識符聲明,基本和Java是一致的,但是細節上會有所變化。

①首字符爲字母,後續字符任意字母和數字,美元符號,可後接下劃線_

② 數字不可以開頭。

③ 首字符爲操作符(比如+ - * / ),後續字符也需跟操作符 ,至少一個(反編譯)

④ 操作符(比如+-*/)不能在標識符中間和最後.

⑤ 用反引號`....`包括的任意字符串,即使是關鍵字(39個)也可以 [true]

2.15.3 標識符舉例說明

hello   // ok
hello12 //ok
1hello // error ,不能以數字開頭
h-b  // error ,不能使用 – 在中間
x h  // error, 不能含有空格
h_4  // ok
_ab  // ok
Int  // ok , Int 是預定義標識符(不是關鍵字)我們要求大家不要這樣使用
Float // ok , 我們要求大家不要這樣使用
_   // error , 編譯不錯,運行錯誤,原因是 _ 有特殊的含義,表示忽略佔位
Abc   // ok 
+*-  // ok
+a // 錯誤

2.15.4 標識符命名注意事項

① 包名:儘量採取有意義的包名,簡短,有意義

② 變量名、函數名 、方法名 採用駝峯法

2.16 Scala關鍵字

•package, import, class, object, trait, extends, with, type, forSome
•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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章