注釋
scala 注釋 與 java 完全一樣
//
單行注釋
/*...*/
多行注釋
/**...*/
文本注釋注釋
命名規(guī)范
Scala中的標(biāo)識符聲明按灶,基本和Java是一致的苗分,但是細(xì)節(jié)上會有所變化,有以下四種規(guī)則:
(1)以字母或者下劃線開頭搬素,后接字母、數(shù)字、下劃線
(2)以操作符開頭铐维,且只包含操作符(+ - * / # !等)
(3)第一種和第二種拼接稚补,第一種在前童叠,二者以下劃線分隔
(4)用反引號....
包括的任意字符串,即使是關(guān)鍵字(39個)也可以
案例
hello // ok
hello12 // ok
1hello // error
h-b // error
x h // error
h_4 // ok
_ab // ok
Int // ok , 因?yàn)樵赟cala Int是預(yù)定義的字符,不推薦
Float // ok
_ // error ,單獨(dú)一個下劃線不可以作為標(biāo)識符
Abc // ok
+*- // ok
+a // error
$a // ok , 但不要讓scala的標(biāo)識符出現(xiàn)$,因?yàn)閟cala編譯器會使用$
關(guān)鍵字
紅色:scala 擴(kuò)展的關(guān)鍵字
藍(lán)色:scala 特定的語法
變量
變量是一種使用方便的占位符课幕,用于引用計(jì)算機(jī)內(nèi)存地址厦坛,變量創(chuàng)建后會占用一定的內(nèi)存空間五垮。
基于變量的數(shù)據(jù)類型,操作系統(tǒng)會進(jìn)行內(nèi)存分配并且決定什么將被儲存在保留內(nèi)存中杜秸。因此放仗,通過給變量分配不同的數(shù)據(jù)類型,你可以在這些變量中存儲整數(shù)亩歹,小數(shù)或者字母匙监。
變量聲明
在學(xué)習(xí)如何聲明變量與常量之前,我們先來了解一些變量與常量小作。
一亭姥、變量: 在程序運(yùn)行過程中其值可能發(fā)生改變的量叫做變量。如:時間顾稀,年齡达罗。
二、常量 在程序運(yùn)行過程中其值不會發(fā)生變化的量叫做常量静秆。如:數(shù)值 3粮揉,字符'A'。
在 Scala 中抚笔,使用關(guān)鍵詞 "var" 聲明變量扶认,使用關(guān)鍵詞 "val" 聲明常量。
聲明變量實(shí)例如下:
var myVar : String = "Foo"
var myVar : String = "Too"
聲明常量實(shí)例如下:可以理解java中的以 final 修飾的變量——常量
val myVal : String = "Foo"
以 var 修飾變量可以修改殊橙,而 val 修飾的變量是一個常量辐宾,是不可以變的
。
以上來自 菜鳥教程
在scala中是可以不用指定變量類型膨蛮,能夠自動轉(zhuǎn)換叠纹。
var i = 10 // Int
var d = 2.3d // Double
var f = 2.3f // Float
var s = "hello" // String
var c ='a' // Char
var b = true // Boolean
使用 val 也是如此
val i = 10
val d = 2.3d
val f = 2.3f
val s = "hello"
val c ='a'
val b = true
也許這樣,看不出來敞葛,此圖(來自idea)
最后:官方推薦使用 val 修飾而不是 var誉察。
字符串
定義字符串
val str="hello"
字符串的拼接
val str="hello"
val str1="world"
val str2 =str+str1 # helloworld
也可以使用 到j(luò)ava中的 的方法
val str2 =str concat(str1) # helloworld
或者簡寫
val str2 =str concat str1 # helloworld
以上兩種方式都算是java的方式,那 scala 有什么方式呢惹谐?在scala支持 插值寫入 的方式持偏,該方式類似于 java中的 format。
語法:s"${}"
val str2 =s"${str}${str1}" # helloworld
或者簡寫
val str2 =s"$str$str1" # helloworld
既然類似于 java中的 format豺鼻,那么在java中這里也是可以使用的
%s 表示字符串综液,除了%s,還有%d儒飒、%c 等谬莹;需要了解到童鞋可以看看這篇博客常規(guī)類型的格式化
val str2 = String.format("%s,%s",str,str1) #hello,world
字符串乘積輸出;思考如何在控制臺輸出20個*?
方式一:
print("********************") # ********************
這種方式附帽,優(yōu)點(diǎn)費(fèi)時埠戳,若是一萬個 *
呢?當(dāng)然你也可以編寫函數(shù)蕉扮,比如使用StringBuilder
整胃。
在scala中有更優(yōu)雅更簡單的方式
print("*"*20) # ********************
其實(shí)scala底層源碼就是采用StringBuilder
實(shí)現(xiàn)的
def * (n: Int): String = {
val buf = new StringBuilder
for (i <- 0 until n) buf append toString
buf.toString
}
千萬不要使用 單引號('')
包括,否則會轉(zhuǎn)換成unicode碼
進(jìn)行相乘喳钟。
print("*"*20) # 840
只有 scala 中的 字符串相關(guān)的方法屁使,大部分都可使用 Java自帶的。
轉(zhuǎn)大寫
val str ="hello"
println(str.toUpperCase) # HELLO
轉(zhuǎn)小寫
val str ="HELLO"
println(str.toLowerCase) # hello
截取
println(str.substring(0,2)) # he
關(guān)于其他方法就不寫了奔则,可以自行了解
輸出打印
用于將結(jié)果打印到控制臺蛮寂,如同java中的System.out.println()
在scala中有三種輸出打印方法
- println() :打印換行
- print() :打印不換行
- printf() :支持格式化打印
關(guān)于println()
和print()
就不講了,很好理解易茬;這里說一下 printf()
酬蹋,可以用于格式化輸出。
val i =1
val n1="小明"
val n2 ="小剛"
val d =5.3d
printf("%s花了%.2f錢抽莱,買了%d個蘋果給%s",n1,d,i,n2) # 小明花了5.30錢范抓,買了1個蘋果給小剛
鍵盤輸入
在編程中,需要接收用戶輸入的數(shù)據(jù)食铐,就可以使用鍵盤輸入語句來獲取匕垫。
StdIn.readLine()、StdIn.readShort()虐呻、StdIn.readDouble()...
引入StdIn
依賴
import scala.io.StdIn
接收一個用戶輸入
def main(args: Array[String]): Unit = {
print("請輸入你的姓名:")
val r=StdIn.readLine()
print(s"你好年缎;${r}同學(xué)")
}
// 請輸入你的姓名:張三
// 你好;張三同學(xué)
除了 readLine
方法铃慷,還包含:
方法 | 參數(shù)值 |
---|---|
readLine | # 接收字符串 |
readBoolean | # 接收布爾類型 |
readByte | # 接收 Byte類型 |
readShort | # 接收 Short類型 |
readChar | # 接收 Char 類型 |
readInt | # 接收 Int 類型 |
readLong | # 接收 Long 類型 |
readFloat | # 接收 Float 類型 |
readDouble | # 接收 Double 類型 |
數(shù)據(jù)類型關(guān)系
AnyVal:數(shù)值類型
AnyRef:引用類型
StringOps:Scala 中對Java中的String增強(qiáng)
Unit:對應(yīng) Java中的void,用于方法返回值的位置蜕该,表示方法沒有返回值犁柜。Unit是一個數(shù)據(jù)類型。只有一個對象就是()堂淡。void 不是數(shù)據(jù)類型馋缅,只是一個關(guān)鍵字。
Null:是一個類型绢淀,只有一個對象就是null萤悴。它是所有引用類型的(AnyRef)的子類
Nothing:是所有數(shù)據(jù)類型的子類,主要用在一個函數(shù)沒有明確返回值時使用皆的,因?yàn)檫@樣我們可以把拋出的返回值覆履,返回給任何的變量或者函數(shù)。
整數(shù)類型(Byte、Short硝全、Int栖雾、Long)
Scala的整數(shù)類型就是用于存放整數(shù)值的,比如12伟众,30析藕,3456等等
數(shù)據(jù)類型 | 描述 |
---|---|
Byte [1] | 8位有符號補(bǔ)碼整數(shù)。數(shù)值區(qū)間為 -128 到 127 |
Short [2] | 16位有符號補(bǔ)碼整數(shù)凳厢。數(shù)值區(qū)間為 -32768 到 32767 |
Int [4] | 32位有符號補(bǔ)碼整數(shù)账胧。數(shù)值區(qū)間為 -2147483648 到 2147483647 |
Long [8] | 64位有符號補(bǔ)碼整數(shù)。數(shù)值區(qū)間為 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1 |
案例:
def main(args: Array[String]): Unit = {
val by:Byte =10
val sho:Short =34
val i =10
val l =1000L
println(s"by=$by,by的類型=${by.getClass.getSimpleName}")
println(s"sho=$sho,sho=${sho.getClass.getSimpleName}")
println(s"i=$i,i的類型=${i.getClass.getSimpleName}")
println(s"l=$l,by的類型=${l.getClass.getSimpleName}")
}
結(jié)果:
by=10,by的類型=byte
sho=34,sho=short
i=10,i的類型=int
l=1000,by的類型=long
當(dāng)然每種類型不能超過自己的作用范圍先紫;例如 byte
正確
var n1:Byte = 127
var n2:Byte = -128
錯誤
var n3:Byte = 128
var n4:Byte = -129
浮點(diǎn)類型(Float治泥、Double)
Scala的浮點(diǎn)類型可以表示一個小數(shù),比如123.4f泡孩,7.8车摄,0.12等等。
數(shù)據(jù)類型 | 描述 |
---|---|
Float [4] | 32 位, IEEE 754標(biāo)準(zhǔn)的單精度浮點(diǎn)數(shù) |
Double [8] | 64位 IEEE 754標(biāo)準(zhǔn)的雙精度浮點(diǎn)數(shù) |
案例:
def main(args: Array[String]): Unit = {
val f =10.23f
val d =56.25d
println(s"f=$f,f的類型=${f.getClass.getSimpleName}")
println(s"d=$d,d的類型=${d.getClass.getSimpleName}")
}
結(jié)果
f=10.23,f的類型=float
d=56.25,d的類型=double
字符類型(Char)
字符類型可以表示單個字符仑鸥,字符類型是Char吮播,16位無符號Unicode字符(2個字節(jié)),區(qū)間值為U+0000到U+FFFF眼俊。
案例
- 字符常量是用單引號 ' ' 括起來的單個字符意狠。
- 可以直接給Char賦一個整數(shù),然后輸出時疮胖,會按照對應(yīng)的unicode字符輸出
def main(args: Array[String]): Unit = {
val man ='男'
val woman ='女'
val a ='a'
val b:Char=98
println(s"man=$man,f的類型=${man.getClass.getSimpleName}")
println(s"woman=$woman,woman的類型=${woman.getClass.getSimpleName}")
println(s"a的unicode=${a.toInt}")
println(s"b=$b")
}
結(jié)果:
man=男,f的類型=char
woman=女,woman的類型=char
a的unicode=97
b=b
在 java 可以實(shí)現(xiàn) char 與 int 相加环戈;char自動轉(zhuǎn)為 int(隱式轉(zhuǎn)換);在scala也是可以的澎灸。
val c ='a'+1
println(c) // 98
若要把int 轉(zhuǎn)為 char 那么需要強(qiáng)制院塞,在scala 中不能使用(類型)
的方式,而是需要用到 前面有介紹的 toXXX
函數(shù)
val c ='a'+1
println(c.toChar) // b
除了這些外性昭,還支持轉(zhuǎn)義字符拦止;如下
符號 | 字符含義 |
---|---|
\n | 換行 (0x0a) |
\r | 回車 (0x0d) |
\f | 換頁符(0x0c) |
\b | 退格 (0x08) |
\0 | 空字符 (0x0) |
\s | 空格 (0x20) |
\t | 制表符 |
" | 雙引號 |
' | 單引號 |
\ | 反斜杠 |
\ddd | 八進(jìn)制字符 (ddd) |
\uxxxx | 16進(jìn)制Unicode字符 (xxxx) |
布爾類型:Boolean
- 布爾類型也叫Boolean類型,Booolean類型數(shù)據(jù)只允許取值true和false
- boolean類型占1個字節(jié)糜颠。
val bool1=true
val bool2:Boolean=false
Unit類型汹族、Null類型和Nothing類型
數(shù)據(jù)類型 | 描述 |
---|---|
Unit | 表示無值,和其他語言中void等同其兴。用作不返回任何結(jié)果的方法的結(jié)果類型顶瞒。Unit只有一個實(shí)例值,寫成()元旬。 |
Null | null , Null 類型只有一個實(shí)例值null |
Nothing | Nothing類型在Scala的類層級的最低端榴徐;它是任何其他類型的子類型守问。當(dāng)一個函數(shù),我們確定沒有正常的返回值箕速,可以用Nothing來指定返回類型酪碘,這樣有一個好處,就是我們可以把返回的值(異常)賦給其它的函數(shù)或者變量(兼容性) |
- Null類只有一個實(shí)例對象盐茎,Null類似于Java中的null引用兴垦。Null可以賦值給任意引用類型(AnyRef),但是不能賦值給值類型(AnyVal)
- Unit類型用來標(biāo)識過程字柠,也就是沒有明確返回值的函數(shù)探越。
由此可見,Unit類似于Java里的void窑业。Unit只有一個實(shí)例——( )钦幔,這個實(shí)例也沒有實(shí)質(zhì)意義 - Nothing,可以作為沒有正常返回值的方法的返回類型常柄,非常直觀的告訴你這個方法不會正常返回鲤氢,而且由于Nothing是其他任意類型的子類,他還能跟要求返回值的方法兼容西潘。
數(shù)值類型間轉(zhuǎn)換
數(shù)值類型自動轉(zhuǎn)換
當(dāng)Scala程序在進(jìn)行賦值或者運(yùn)算時卷玉,精度小的類型自動轉(zhuǎn)換為精度大的數(shù)值類型,這個就是自動類型轉(zhuǎn)換(隱式轉(zhuǎn)換)喷市。數(shù)據(jù)類型按精度(容量)大小排序?yàn)椋?br>
(1)自動提升原則:有多種類型的數(shù)據(jù)混合運(yùn)算時相种,系統(tǒng)首先自動將所有數(shù)據(jù)轉(zhuǎn)換成精度大的那種數(shù)據(jù)類型,然后再進(jìn)行計(jì)算品姓。
(2)當(dāng)我們把精度大的數(shù)值類型賦值給精度小的數(shù)值類型時寝并,就會報錯,反之就會進(jìn)行自動類型轉(zhuǎn)換腹备。
def main(args: Array[String]): Unit = {
val i:Int =10
val l:Long=200
val r =i+l
println(s"r=$r,r的數(shù)據(jù)類型為${r.getClass.getSimpleName}") // r=210,r的數(shù)據(jù)類型為long
}
def main(args: Array[String]): Unit = {
val i:Int =10
val l:Long=200
val d:Double=56.23
val r =i+l+d
println(s"r=$r,r的數(shù)據(jù)類型為${r.getClass.getSimpleName}") // r=266.23,r的數(shù)據(jù)類型為double
}
(3)(byte衬潦,short)和char之間不會相互自動轉(zhuǎn)換。
(4)byte植酥,short别渔,char他們?nèi)呖梢杂?jì)算,在計(jì)算時首先轉(zhuǎn)換為int類型惧互。
def main(args: Array[String]): Unit = {
val b:Byte =1
val s:Short=2
val c:Char='a'
val r =b+s+c
println(s"r=$r,r的數(shù)據(jù)類型為${r.getClass.getSimpleName}")
}
r=100,r的數(shù)據(jù)類型為int
強(qiáng)制類型轉(zhuǎn)換
在java中強(qiáng)制轉(zhuǎn)換需要使用(類型)
的方式,scala中不支持這樣操作喇伯,若需要強(qiáng)制轉(zhuǎn)換那么就要使用到toXXX
函數(shù)
自動類型轉(zhuǎn)換的逆過程喊儡,將精度大的數(shù)值類型轉(zhuǎn)換為精度小的數(shù)值類型。使用時要加上強(qiáng)制轉(zhuǎn)函數(shù)稻据,但可能造成精度降低或溢出艾猜,格外要注意买喧。
def main(args: Array[String]): Unit = {
val i:Int =10
val d:Double=56.23
val ii=i.toDouble
val dd=d.toInt
println(s"ii=$ii,ii的數(shù)據(jù)類型為${ii.getClass.getSimpleName}") // ii=10.0,ii的數(shù)據(jù)類型為double
println(s"dd=$dd,dd的數(shù)據(jù)類型為${dd.getClass.getSimpleName}") // dd=56,dd的數(shù)據(jù)類型為int
}
上面有演示
Char類型可以保存Int的常量值,但不能保存Int的變量值匆赃,需要強(qiáng)轉(zhuǎn)
Byte和Short類型在進(jìn)行運(yùn)算時淤毛,當(dāng)做Int類型處理。
數(shù)值類型和String類型間轉(zhuǎn)換
在程序開發(fā)中算柳,我們經(jīng)常需要將基本數(shù)值類型轉(zhuǎn)成String類型低淡。或者將String類型轉(zhuǎn)成基本數(shù)值類型瞬项。
基本類型轉(zhuǎn)String類型
方式一:(語法:將基本類型的值+"" 即可)
def main(args: Array[String]): Unit = {
val i =10
val r="aa"+i
println(r) // aa10
}
方式二:*.toString
def main(args: Array[String]): Unit = {
val i=65
val ii=i.toString
println(s"ii=$ii,ii的數(shù)據(jù)類型為${ii.getClass.getSimpleName}") // ii=65,ii的數(shù)據(jù)類型為String
}
String類型轉(zhuǎn)基本數(shù)值類型(語法:s1.toInt蔗蹋、s1.toFloat、s1.toDouble囱淋、s1.toByte猪杭、s1.toLong、s1.toShort)
如:字符串轉(zhuǎn) Double
def main(args: Array[String]): Unit = {
val s1="52.36"
val ii=s1.toDouble
println(s"ii=$ii,ii的數(shù)據(jù)類型為${ii.getClass.getSimpleName}") //ii=52.36,ii的數(shù)據(jù)類型為double
}
注意:
在將String類型轉(zhuǎn)成基本數(shù)值類型時妥衣,要確保String類型能夠轉(zhuǎn)成有效的數(shù)據(jù)皂吮,比如我們可以把"123",轉(zhuǎn)成一個整數(shù)税手,但是不能把"hello"轉(zhuǎn)成一個整數(shù)蜂筹。
運(yùn)算符
算術(shù)運(yùn)算符
運(yùn)算符 | 運(yùn)算 | 范例 | 結(jié)果 |
---|---|---|---|
+ | 正號 | +3 | 3 |
- | 負(fù)號 | b=4; | -b -4 |
+ | 加 | 5+5 | 10 |
- | 減 | 6-4 | 2 |
* | 乘 | 3*4 | 12 |
/ | 除 | 5/5 | 1 |
% | 取模(取余) | 7%5 | 2 |
+ | 字符串相加 | “He”+”llo” | “Hello” |
(1)對于除號“/”,它的整數(shù)除和小數(shù)除是有區(qū)別的:整數(shù)之間做除法時冈止,只保留整數(shù)部分而舍棄小數(shù)部分狂票。
(2)對一個數(shù)取模a%b,和Java的取模規(guī)則一樣
關(guān)系運(yùn)算符(比較運(yùn)算符)
運(yùn)算符 | 運(yùn)算 | 范例 | 結(jié)果 |
---|---|---|---|
== | 相等于 | 4==3 | false |
!= | 不等于 | 4熙暴!=3 | true |
< | 小于 | 4<3 | false |
> | 大于 | 4>3 | true |
<= | 小于等于 | 4<=3 | false |
>= | 大于等于 | 4>=3 | true |
邏輯運(yùn)算符
用于連接多個條件(一般來講就是關(guān)系表達(dá)式)闺属,最終的結(jié)果也是一個Boolean值。
假定:變量A為true周霉,B為false
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
&& | 邏輯與 | (A && B) 運(yùn)算結(jié)果為 false |
|| | 邏輯或 | (A || B) 運(yùn)算結(jié)果為 true |
! | 邏輯非 | !(A && B) 運(yùn)算結(jié)果為 true |
賦值運(yùn)算符
賦值運(yùn)算符就是將某個運(yùn)算后的值掂器,賦給指定的變量。
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
= | 簡單的賦值運(yùn)算符俱箱,將一個表達(dá)式的值賦給一個左值 | C = A + B 將 A + B 表達(dá)式結(jié)果賦值給 C |
+= | 相加后再賦值 | C += A 等于 C = C + A |
-= | 相減后再賦值 | C -= A 等于 C = C - A |
*= | 相乘后再賦值 | C *= A 等于 C = C * A |
/= | 相除后再賦值 | C /= A 等于 C = C / A |
%= | 求余后再賦值 | C %= A 等于 C = C % A |
<<= | 左移后賦值 | C <<= 2 等于 C = C << 2 |
>>= | 右移后賦值 | C >>= 2 等于 C = C >> 2 |
&= | 按位與后賦值 | C &= 2 等于 C = C & 2 |
^= | 按位異或后賦值 | C ^= 2 等于 C = C ^ 2 |
|= | 按位或后賦值 | C |= 2 等于 C = C | 2 |
注意:Scala中沒有++国瓮、--操作符,需要通過+=狞谱、-=來實(shí)現(xiàn)同樣的效果
位運(yùn)算符
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
& | 按位與運(yùn)算符 | (a & b) 輸出結(jié)果 12 乃摹,二進(jìn)制解釋: 0000 1100 |
| | 按位或運(yùn)算符 | (a | b) 輸出結(jié)果 61 ,二進(jìn)制解釋: 0011 1101 |
^ | 按位異或運(yùn)算符 | (a ^ b) 輸出結(jié)果 49 跟衅,二進(jìn)制解釋: 0011 0001 |
~ | 按位取反運(yùn)算符 | (~a ) 輸出結(jié)果 -61 孵睬,二進(jìn)制解釋: 1100 0011, 在一個有符號二進(jìn)制數(shù)的補(bǔ)碼形式伶跷。 |
<< | 左移動運(yùn)算符 | a << 2 輸出結(jié)果 240 掰读,二進(jìn)制解釋: 1111 0000 |
>> | 右移動運(yùn)算符 | a >> 2 輸出結(jié)果 15 秘狞,二進(jìn)制解釋: 0000 1111 |
>>> | 無符號右移 | A >>>2 輸出結(jié)果 15, 二進(jìn)制解釋: 0000 1111 |
scala 中實(shí)現(xiàn) i++ 及 i-- 操作
i++
def main(args: Array[String]): Unit = {
var i=0;
i-=1
println(i) // -1
}
i--
def main(args: Array[String]): Unit = {
var i=0;
i+=1
println(i) // 1
}
至于為什么 scala 不支持 i++ 及 i--;大部分網(wǎng)友說蹈集,開發(fā)者認(rèn)為i++ 烁试,i-- 可讀性太差,理解起來不好拢肆。
比如:
public static void main(String[] args) {
int a=10;
a=a++;
a=a++;
a=a++;
System.out.println("a="+a);
int b=10;
b=++b;
b=++b;
b=++b;
System.out.println("b="+b);
}
思考一下减响,a=多少?b=多少善榛?
a=10
b=13
i+=辩蛋,i-= 的方式;理解起來就會簡單很多
public static void main(String[] args) {
int a=10;
a+=1;
a+=1;
a+=1;
System.out.println("a="+a);
int b=10;
b-=1;
b-=1;
b-=1;
System.out.println("b="+b);
}
a=13
b=7