本文是對Scala語言的基本語法的一個學(xué)習(xí)總結(jié)帖鸦,共包括如下章節(jié):
- 基本元素
- 結(jié)構(gòu)化語句
- 數(shù)據(jù)類型
- 小結(jié)
參考資料:
1证杭、如果需要對scala的基本概念和開發(fā)環(huán)境搭建進(jìn)行了解陨献,可參考文章《Scala學(xué)習(xí)筆記(1)-快速起步》潭陪。
一垒迂、基本元素
(一)數(shù)據(jù)類型
scala是一種強(qiáng)類型語言畔派,所有數(shù)據(jù)都是有類型的姥饰。scala的數(shù)據(jù)類型可分為兩種:
1爷绘、一種是scala預(yù)定義的一些數(shù)據(jù)類型,比如預(yù)定義的值類型(如Int老充,Char等)葡盗、預(yù)定義的引用類型(如字符串類型String)。
2啡浊、另一種是自定義的數(shù)據(jù)類型戳粒,如自定義類。
(二)基礎(chǔ)數(shù)據(jù)類型
scala中有如下基礎(chǔ)數(shù)據(jù)類型虫啥,與Java中是一致的。如下表所列:
類型名 | 含義 | 類型名 | 含義 |
---|---|---|---|
Byte | 8位有符號整數(shù) | Float | 32位單精度浮點數(shù) |
Short | 16位有符號整數(shù) | Double | 32位雙精度浮點數(shù) |
Int | 32位有符號整數(shù) | Char | 16位無符號數(shù) |
Long | 64位有符號整數(shù) | Boolean | 布爾型奄妨,true或false |
需要注意的是涂籽,scala并沒有基本類型,scala是一種純面向?qū)ο蟮木幊陶Z言砸抛。它的每一個基礎(chǔ)類型都是一個類评雌。當(dāng)把一個scala應(yīng)用程序編譯成java字節(jié)碼的時候,編譯器會自動把scala基礎(chǔ)類型轉(zhuǎn)變成java基本類型直焙,這樣有助于提高應(yīng)用程序的性能景东。
(三)變量定義
scala有兩種類型的變量:可變和不可變的。
可變變量使用關(guān)鍵字var聲明奔誓,可以在創(chuàng)建之后重新賦值斤吐,如:
var x = 10
x =20
不可變變量使用關(guān)鍵字val聲明,在初始化之后不可以重新賦值了厨喂,如:
val y = 10
y =20 //這個語句會報編譯器錯誤
scala語言的變量定義有下特點:
1和措、需要用關(guān)鍵字var 或 val來定義
2、變量定義時就必須進(jìn)行初始化賦值
3蜕煌、變量定義時可以省去類型名派阱,會根據(jù)賦值進(jìn)行類型推斷,如下面兩個語句是等價的:
var x: Int= 10
var x =10
如果要聲明類型斜纪,類型名在變量名后面贫母,之間以冒號分隔。顯然盒刚,不加類型代碼更簡潔腺劣。
(四)字面量
scala中各數(shù)據(jù)類型的字面量與java中的一致。
(五)表達(dá)式
表達(dá)式是可計算的語句伪冰,每個表達(dá)式都有一個返回值誓酒。
(六)語句塊
利用{}將多個語句組成一個語句塊,語句塊也是有返回值的,塊中最后一個表達(dá)式的結(jié)果也是整個塊的結(jié)果靠柑。如下面是合法的代碼:
object Hello {
def main(args: Array[String]) {
var x=
{
val x = 1 + 1
x + 1
}
println(x)
}
}
(七)類
scala是一種純面向?qū)ο蟮木幊陶Z言寨辩,類是面向?qū)ο缶幊痰幕締卧械拇a都包含在類中歼冰。scala的類和Java中的類基本相似靡狞,但也有一些自己的特點。下面是一個簡單的類的定義:
class Person{
var name:String="tom"
def show()={
println(name)
}
}
上面代碼中定義了一個Person類隔嫡,類中有一個成員變量name和一個成員方法show甸怕,可以看出,和java中的類定義類似腮恩。
scala中的類是一種用戶自定義的數(shù)據(jù)類型梢杭。關(guān)于scala的類及面向?qū)ο蟮木幊痰母敿?xì)的信息我們在后面的文章中介紹。
(八)函數(shù)和方法
函數(shù)和方法這兩個名詞在很多語言中都會提到秸滴,通常來說武契,在類中定義的作為類的成員的函數(shù)稱為方法。比如在c語言中荡含,沒有類的概念咒唆,所以沒有方法的概念,所以全部稱為函數(shù)释液。而在c++中全释,函數(shù)既可以獨立在類的外部,也可以定義在類的內(nèi)部作為類的成員误债,所以在類的外部定義時我們稱為函數(shù)浸船,在類的內(nèi)部作為成員定義時我們稱為方法。
函數(shù)還是方法都是完成一個特定功能的代碼集合找前,無論是函數(shù)還是方法糟袁,都有幾個共同的特性:
1、輸入?yún)?shù)列表躺盛,每個函數(shù)或方法都可以有0個或多個參數(shù)
2项戴、返回值,函數(shù)或方法都會有一個返回值
3槽惫、代碼周叮,函數(shù)或方法通過其包含的代碼來完成其設(shè)定的功能。只有被調(diào)用后界斜,代碼才會被執(zhí)行仿耽。
在scala中,我們使用def關(guān)鍵字定義方法(如上面Person類中的show方法)各薇,scala中的方法的語法和java中的方法類似项贺。關(guān)于scala中方法的詳細(xì)介紹君躺,參見《Scala學(xué)習(xí)筆記(3)-面向?qū)ο缶幊躺掀?/a>;關(guān)于scala函數(shù)的含義开缎,以及函數(shù)與方法的區(qū)別棕叫,參見《Scala學(xué)習(xí)筆記(5)-函數(shù)式編程》中的介紹。
二奕删、結(jié)構(gòu)化語句
(一)if條件語句
scala的if條件語句語法與java的完全一致俺泣,本文不再介紹。
需要說明一點的是完残,在scala中伏钠,任何語句都是一個表達(dá)式,表達(dá)式都是有值的谨设。if語句也不例外熟掂,可以將if作為一個表達(dá)式賦值給變量。如下面的例子:
scala> val re = if(3>1) println("A")
A
re: Unit = ()
scala> val re = if(3>5) println("A")
re: Unit = ()
scala> val re = if(3>5) 10 else 5
re: Int = 5
if語句作為一個表達(dá)式扎拣,其返回值實際是if語句中最后一個被執(zhí)行語句的返回值打掘。上面代碼中,第一個if語句最后執(zhí)行的是 println("A") 語句鹏秋,因為println方法的返回值是Unit類型,Unit類型具有唯一實例()亡笑,后面會詳細(xì)介紹侣夷,這里理解成java中的void即可。第二個if語句沒有滿足條件的語句被執(zhí)行仑乌,返回值也是Unit類型百拓,值為()。第三個if語句晰甚,最后執(zhí)行的語句就是個整數(shù)表達(dá)式5,所以返回的類型是Int型衙传,值為5。
(二)循環(huán)語句
1厕九、while循環(huán)
scala語言提供了和java中一樣用法的while循環(huán)和do while循環(huán)蓖捶。下面看一個使用while循環(huán)的簡單例子:
scala> var i=1
i: Int = 1
scala> while(i<5){
| print(i+",")
| i=i+1
| }
1,2,3,4,
scala>
2、for循環(huán)
scala語言提供了for循環(huán)語句扁远,和c/c++/java不同的是俊鱼,沒有for(初始化變量;條件判斷;更新變量)這樣的循環(huán)語法,而是支持對集合的遍歷來實現(xiàn)循環(huán)(類似Java中for語句對Java的遍歷)畅买。for循環(huán)的語法格式如下:
for(元素變量 <- 集合對象){
.....循環(huán)代碼
}
如果循環(huán)體代碼只有一條語句并闲,則{}可省略。
我們來看一個簡單例子:
scala> var list = List("hello ","world ","good")
list: List[String] = List("hello ", "world ", good)
scala> for(item <- list){
| print(item)
| }
hello world good
scala>
上面代碼中的list變量是一個List類型的實例谷羞,List是scala中的列表集合帝火,和Java中的List接口類似。
3、有過濾條件的for循環(huán)犀填,語法格式如:
for(元素變量 <- 集合對象 if條件判斷1; if條件判斷2.....){
//所有條件都滿足才執(zhí)行循環(huán)中的語句
}
下面看一個具體的例子蠢壹,如下:
scala> var list = List(1,5,2,7,4)
list: List[Int] = List(1, 5, 2, 7, 4)
scala> for(item <- list if item>2;if item<7) print(item)
54
scala>
說明,條件不滿足并不是結(jié)束(或跳出)整個for循環(huán)宏浩,而是不執(zhí)行本次循環(huán)體中的語句知残。
關(guān)于如何跳出循環(huán),下面會進(jìn)行介紹比庄。
同if語句一樣求妹,循環(huán)語句也可以作為一個表達(dá)式,也有返回值佳窑,可以賦值給變量制恍,只不過scala的循環(huán)語句,無論是while還是for神凑,不管循環(huán)體中是什么代碼净神,當(dāng)作表達(dá)式時,返回值的類型總是為Unit溉委。如下面例子:
scala> val re = for(i<-List(2,3)) 5
re: Unit = ()
scala> val re = for(i<-List(2,3)) print(i)
23re: Unit = ()
可以看出鹃唯,無論循環(huán)體中執(zhí)行的是一個表達(dá)式,還是一個返回值為Unit的方法調(diào)用瓣喊,for循環(huán)作為一個表達(dá)式返回值都是Unit類型坡慌。
(三)跳出循環(huán)
前面我們介紹了scala中的循環(huán)語句,但一直沒有提到如何跳出循環(huán)藻三,在java中洪橘,提供了break和continue的關(guān)鍵字用于跳出循環(huán)和提前結(jié)束本次循環(huán),但scala中沒有這兩個關(guān)鍵字棵帽。在scala中熄求,可以通過其它方法來結(jié)束循環(huán)。
實現(xiàn)contine關(guān)鍵字的功能比較簡單逗概,只需通過if語句來實現(xiàn)弟晚。我們看一段Java代碼使用contine關(guān)鍵字的例子:
int i=10;
while(i>0){
i=i-1;
if(i%2==0){
continue;
}
System.out.println(i);
}
上面代碼不用continue關(guān)鍵字,只需改變下if語句逾苫,如下面代碼是scala中的實現(xiàn):
var i=10
while(i>0){
i=i-1
if(i%2!=0){
println(i)
}
}
不過想替代break關(guān)鍵字指巡,尤其是對于for循環(huán),就相對麻煩一些了隶垮。下面我們來看看怎么處理藻雪。
方法一:通過變量來控制
對于while循環(huán),因為天生其條件就是布爾表達(dá)式狸吞,只需在循環(huán)體中根據(jù)情況修改變量的值勉耀,讓條件表達(dá)式為false指煎,就可以結(jié)束循環(huán)。對于for循環(huán)便斥,也可以加上一個條件變量來實現(xiàn)至壤,如下面例子:
var list = List(1,5,-1,7,4)
var flag=true
for(item <- list if flag){
if(item<0)
flag=false
else
print(item)
}
顯然對于for循環(huán),這不是一種好的方式枢纠,因為效果上能實現(xiàn)類似跳出循環(huán)像街,但實際是計算flag值為false后,對于集合中的剩余元素晋渺,每個元素還是得判斷一下镰绎,只是因為flag的值一直為false了,循環(huán)體不會被執(zhí)行木西。
方法二:使用scala.util.control.Breaks類
Breaks類中的breakable方法可以跟一代碼塊畴栖,在代碼塊中調(diào)用Breaks類的break方法可以跳出這個代碼塊,如下面例子:
import scala.util.control.Breaks._
println("begin")
breakable{
println("a1")
break
println("a2")
}
println("end")
上面代碼首先通過import語句將Breaks類引入八千。breakable方法后跟著的是代碼塊吗讶,實際這是breakable方法的參數(shù),如果我們查看breakable方法的源代碼恋捆,會發(fā)現(xiàn)breakable方法的參數(shù)就是一個不帶任何參數(shù)的函數(shù)類型照皆。而一個代碼塊就可以看作是不帶參數(shù)的函數(shù),所以可以傳遞給breakable方法沸停。在該代碼塊中纵寝,我們調(diào)用了break方法。執(zhí)行上述代碼星立,我們會發(fā)現(xiàn)break語句后面的 println("a2") 語句沒有被執(zhí)行。
有了Breaks這個類的功能葬凳,我們只需將循環(huán)代碼放入到breakable方法的參數(shù)代碼塊中绰垂,然后在循環(huán)體中根據(jù)條件調(diào)用Breaks類的break方法,這樣就可以跳出整個代碼塊火焰,也就跳出了循環(huán)劲装。如上面for循環(huán)例子可這樣實現(xiàn):
import scala.util.control.Breaks._
var list = List(1,5,-1,7,4)
breakable{
for(item <- list){
if(item<0) break
print(item)
}
}
顯然,我們也可以很容易的實現(xiàn)嵌套循環(huán)中從內(nèi)循環(huán)中跳到最外部昌简,如下面例子:
import scala.util.control.Breaks._
var list = List(1,5,-1,7,4)
breakable{
for(i <- List(1,2,3))
for(item <- list){
if(item<0) break
print(item)
}
}
可以看出占业,使用Breaks類提供的方法來跳出循環(huán),在簡單場景下和java中使用break關(guān)鍵字有點類似纯赎,但Breaks類的功能更加強(qiáng)大和通用谦疾。
方法三:使用內(nèi)嵌方法和return語句
我們可以將循環(huán)語句放入到一個方法中,然后當(dāng)條件滿足時犬金,使用return語句念恍,這樣方法都結(jié)束了六剥,自然循環(huán)就結(jié)束了。如下面例子:
def func(){
println("begin")
def test(){
for(item <- List(1,5,-1,7,4) ){
if(item<0)
return
println(item)
}
}
test()
println("end")
}
func()
上面代碼在方法func的內(nèi)部定義了一個test方法峰伙,在test方法的for循環(huán)中使用return語句提前結(jié)束方法疗疟,也就是提前結(jié)束了循環(huán)。這種方式雖然可以實現(xiàn)跳出循環(huán)瞳氓,但要顯示定義一個方法策彤,顯然降低了代碼的整潔度。
三匣摘、數(shù)據(jù)類型
(一)概述
scala是一種純面向?qū)ο蟮木幊陶Z言店诗,所有的數(shù)據(jù)類型都是類,所有的值都是對象恋沃。scala語言中所有的類都繼承自一個共同的超類Any,是scala類層級的根節(jié)點必搞,在其下面有兩個子類:AnyVal和AnyRef。
其中AnyVal是Scala中所有值類型的超類囊咏,scala中有9種預(yù)定義的值類型恕洲,這9種預(yù)定義的值類型分別是Double,Float,Long,Int,Short,Byte,Unit,Char和Boolean。值類型的實例必須都有值梅割。
AnyRef 代表引用類型霜第,全部的非值類型都被定義為引用類型。在Scala中預(yù)定義的一些類型户辞,如字符串類型String,集合類型List,Set等,以及用戶自定義的每個類型都是 AnyRef 的子類型泌类。AnyRef 相當(dāng)于java中的java.lang.Object類。
下圖顯示了scala的類型層次關(guān)系底燎。
在上圖的scala類型層次圖中我們看到最下面還有Null和Nothing兩個類型刃榨,后面會專門介紹。
(二)基礎(chǔ)類型的隱式(implict)轉(zhuǎn)換
上面提到双仍,AnyVal類型的子類中枢希,有9種預(yù)定義的值類型分別是Double,Float,Long,Int,Short,Byte,Char,Boolean和Unit朱沃。除Boolean和Unit類型外苞轿,其它的值型之間可以實現(xiàn)隱式的轉(zhuǎn)換。它們的轉(zhuǎn)換關(guān)系如下:
也就是按照上圖箭頭的方向逗物,比如Byte類型的數(shù)據(jù)可以直接賦值給Short及之后的類型的變量搬卒。因為越是往后,類型的存儲范圍越大翎卓,高范圍的可與容納低范圍的契邀,反之不行。如:
scala> var b:Byte=100
b: Byte = 100
scala> var s:Short=50
s: Short = 50
scala> s=b
s: Short = 100
scala> b=s
<console>:13: error: type mismatch;
found : Short
required: Byte
b=s
從上面例子可以看出失暴,Byte類型的變量賦值給Short類型的沒問題蹂安,反之會報錯椭迎。Char類型雖然是保存的字符,可以賦值給Int類型及后面的類型田盈,賦值時會自動按照ASCII碼來轉(zhuǎn)換,但反之不行畜号。不過可以將字面量的整數(shù)賦值給Char類型,會自動轉(zhuǎn)換為字符允瞧。如:
scala> var c:Char='a'
c: Char = a
scala> c=98
c: Char = b
scala> var a:Int = c
a: Int = 98
scala> c=a
<console>:13: error: type mismatch;
found : Int
required: Char
c=a
^
(三)Null和Nothing
前面的scala類型層次圖中我們看到最下面還有Null和Nothing兩個類型简软。
其中Null 是所有引用類型的子類型(也就是說是AnyRef 的任何子類型)。它具有唯一的實例null(是個關(guān)鍵字)述暂。null 主要是為了和其它JVM語言的交互而提供的痹升,并且應(yīng)該永遠(yuǎn)不要在Scala代碼中使用它。
Nothing 是所有類型的子類型(包括Null類型)畦韭,也叫做底部類型疼蛾。但是Nothing類卻不存在任何實例。Nothing的主要用處體現(xiàn)在兩個地方:
1艺配、在定義空列表時使用察郁,如:
scala> var list = List()
list: List[Nothing] = List()
2、作為方法不正常返回的返回類型使用转唉,如:
def error(msg:String):Nothing={
throw new RuntimeException(msg)
}
def divide(x: Int, y: Int): Int ={
if (y != 0)
x / y
else
error("can not divide by zero")
}
(四)Unit類型
9種值類型中還有一個Unit類型皮钠,這個在java中沒有對應(yīng)的類型,它是scala中一種特殊的類型赠法,有唯一的實例() 麦轰,代表沒有值,類似c或Java中的void砖织。通常用作不返回任何結(jié)果的方法的結(jié)果類型款侵。如:
scala> val re = println("hello")
hello
re: Unit = ()
scala> def test() = {}
test: ()Unit
在上面的第一個例子中,println函數(shù)只是輸出信息侧纯,不返回任何結(jié)果新锈。這時調(diào)用時返回的就是()值。第二個例子茂蚓,定義了一個空函數(shù),顯示函數(shù)的返回類型就是Unit類型剃幌。
當(dāng)然我們也可以顯示的定義一個方法的返回值為Unit類型聋涨,如:
def test(info:String):Unit={
println(info)
}
(五)Option類型
大多數(shù)語言都有一個特殊的關(guān)鍵字或者對象來表示一個對象引用的是“無”,在Java中负乡,它是null牍白。在Java 里,null 是一個關(guān)鍵字抖棘,不是一個對象茂腥,所以對它調(diào)用任何方法都是非法的狸涌。但是這對語言設(shè)計者來說是一件令人疑惑的選擇。為什么要在程序員希望返回一個對象的時候返回一個關(guān)鍵字呢最岗?
在前面部分已經(jīng)提到帕胆,scala中的Null類型,有唯一的實例null(是個關(guān)鍵字)般渡,實際上scala提供null主要是為了和其它JVM語言的交互而提供的懒豹,并且應(yīng)該永遠(yuǎn)不要在Scala代碼中使用它。
在scala中驯用,我們應(yīng)該使用Option類型脸秽。Scala中的Option(選項)類型用來表示一個值是可選的(有值或無值)。它是一個泛型類型蝴乔,Option[T] 是一個類型為 T 的可選值的容器: 如果值存在记餐, Option[T] 的值就是Some[T] ,如果不存在薇正, Option[T] 的值就是 None 片酝。
Scala程序使用Option非常頻繁,在Java中使用null來表示空值铝穷,代碼中很多地方都要添加null關(guān)鍵字檢測钠怯,不然很容易出現(xiàn)NullPointException。因此Java程序需要關(guān)心那些變量可能是null,而這些變量出現(xiàn)null的可能性很低曙聂,但一但出現(xiàn)晦炊,很難查出為什么出現(xiàn)NullPointerException。 Scala的Option類型可以避免這種情況宁脊,因此Scala應(yīng)用推薦使用Option類型來代表一些可選值断国。比如如果一個函數(shù)的返回值可能不會引用任何值,則返回類型可以定義為Option類型榆苞,這樣調(diào)用者一眼就可以看出這種類型的值可能為None稳衬。
比如scala提供的數(shù)據(jù)結(jié)構(gòu)map,其get方法(根據(jù)key獲取value)返回的就是一個Option類型坐漏。這么設(shè)計的原因是因為key有可能不存在薄疚。我們看一個例子:
scala> val myMap: Map[String, String] = Map("key1" -> "hello")
myMap: Map[String,String] = Map(key1 -> hello)
scala> val value1: Option[String] = myMap.get("key1")
value1: Option[String] = Some(hello)
scala> val value2: Option[String] = myMap.get("key2")
value2: Option[String] = None
scala> var re = value1.get
re: String = hello
可以看出因為map中存在鍵為key1的數(shù)據(jù),所以調(diào)用map的get方法返回的是Option類型的實例 Some(hello) 赊琳;而鍵key2不存在街夭,返回的是Option類型的另一個實例None。對于Some[T]躏筏,通過調(diào)用它的get方法板丽,可以獲取T值。
顯然在實際使用時趁尼,我們并不知道返回的Option對象的值是Some還是None埃碱,所以并不能不經(jīng)過判斷直接調(diào)用get猖辫,這有很多種解決方法:
1、先判斷值是否是None砚殿,如:
scala> val myMap: Map[String, String] = Map("key1" -> "hello")
myMap: Map[String,String] = Map(key1 -> hello)
scala> val value1: Option[String] = myMap.get("key1")
value1: Option[String] = Some(hello)
scala> if (value1!=None){
| print(value1.get)
| }
hello
判斷一個Option對象的值是否為None啃憎,最好的方式是調(diào)用Option的isEmpty方法,如:
scala> val myMap: Map[String, String] = Map("key1" -> "hello")
myMap: Map[String,String] = Map(key1 -> hello)
scala> val value1: Option[String] = myMap.get("key1")
value1: Option[String] = Some(hello)
scala> if (!value1.isEmpty) print(value1.get)
hello
不過在scala中瓮具,還有比使用if語句更好的方式荧飞,就是利用scala的match功能。
2名党、使用match功能叹阔,如
scala> val myMap: Map[String, String] = Map("key1" -> "hello")
myMap: Map[String,String] = Map(key1 -> hello)
scala> val value1: Option[String] = myMap.get("key1")
value1: Option[String] = Some(hello)
scala> val re = value1 match{
| case Some(v) => v
| case None => "?"
| }
re: String = hello
可以看出,使用match語句传睹,如果不存在值返回一個默認(rèn)值耳幢。
3、利用Option的getOrElse方法
Option的getOrElse方法可以設(shè)置一個默認(rèn)值欧啤,當(dāng)Option對象有值時睛藻,返回具體的值,當(dāng)沒有值時邢隧,返回默認(rèn)值店印。如下面例子:
scala> val myMap: Map[String, String] = Map("key1" -> "hello")
myMap: Map[String,String] = Map(key1 -> hello)
scala> val re1 = myMap.get("key1").getOrElse("?")
re1: String = hello
scala> val re2 = myMap.get("key2").getOrElse("?")
re2: String = ?
Option類除了有上面介紹的get方法、isEmpty方法倒慧、getOrElse方法按摘,還有很多其它方法,這里不再一一介紹纫谅。
4炫贤、使用for循環(huán)
上面我們提到在Scala里Option[T]實際上是一個容器,就像數(shù)組或是List一樣付秕,你可以把他看成是一個可能有零個或一個元素的List兰珍。當(dāng)Option里面有東西的時候,這個List的長度是1(也就是 Some)询吴,而當(dāng)你的Option里沒有東西的時候掠河,它的長度是0(也就是 None)。
如果我們把Option當(dāng)成一般的List來用猛计,并且用一個for循環(huán)來走訪這個Option的時候唠摹,如果Option是None,那這個for循環(huán)里的程序代碼自然不會執(zhí)行有滑,于是我們就達(dá)到了不用檢查Option是否為None這件事跃闹。如下面例子:
scala> val myMap: Map[String, String] = Map("key1" -> "hello")
myMap: Map[String,String] = Map(key1 -> hello)
scala> val value1: Option[String] = myMap.get("key1")
value1: Option[String] = Some(hello)
scala> for(item<-value1) println(item);
hello
scala> val value2: Option[String] = myMap.get("key2")
value2: Option[String] = None
scala> for(item<-value2) println(item);
scala>
從上面例子可以看出嵌削,因為value2中沒有值毛好,所以第二個for循環(huán)中的代碼就沒有被執(zhí)行望艺。
(六)元組類型
元組是scala中的一種數(shù)據(jù)類型,它是不同類型值的聚集肌访,它可以將不同類型的值存放在一個變量中保存找默。如下面例子:
scala> var data=("hello",12,true)
data: (String, Int, Boolean) = (hello,12,true)
scala> var data: (String, Int, Boolean) =("hello",12,true)
data: (String, Int, Boolean) = (hello,12,true)
上面代碼定義了一個元組類型的變量data,值為("hello",12,true)吼驶,可以看出元組的類型名并不是統(tǒng)一的一個名稱惩激,而是跟值有關(guān)系。上面元組變量data對應(yīng)的類型名為(String, Int, Boolean)蟹演。
元組最大的方便之處就可以將多個值放在一起风钻,后面可以很方便的提取其中的各個值到多個單獨的變量中。如下面例子:
scala> var (a,b,c) =data
a: String = hello
b: Int = 12
c: Boolean = true
可以看出酒请,通過 var (a,b,c) =data 這樣的操作骡技,將data元組中的3個值提取到了a,b,c三個獨立的變量中。這個特性尤其在方法返回多個值時很有用羞反。
(七)符號類型
scala的符號類型(名稱為Symbol)布朦,主要其標(biāo)識作用≈绱埃可以采用如下的方式定義符號類型:
scala> var s1 = 'tag
s1: Symbol = 'tag
scala> var s2:Symbol = 'tag
s2: Symbol = 'tag
在標(biāo)識符前面加上’就定義了一個符號類型的值是趴。上面代碼定義了兩個符號類型變量,s1沒有顯示聲明類型名澄惊,由scala自動推斷出來唆途;s2顯示的聲明類型為Symbol。
四缤削、小結(jié)
本文對scala的基本語法窘哈、結(jié)構(gòu)化語句、數(shù)據(jù)類型等知識進(jìn)行了總結(jié)亭敢,在后面的文章中會對scala面向?qū)ο蠊鐾瘛⒚嫦蚝瘮?shù)的編程特性進(jìn)行介紹。