Scala的基本類(lèi)型及文本化
Scala的基本類(lèi)型
表格5.1顯示了Scala的許多基本的類(lèi)型和其實(shí)例值域范圍??傮w來(lái)說(shuō),類(lèi)型Byte,Short,Int,Long和Char被稱(chēng)為整數(shù)類(lèi)型:integral type。整數(shù)類(lèi)型加上Float和Double被稱(chēng)為數(shù)類(lèi)型:numeric type。
51CTO編輯推薦:Scala編程語(yǔ)言專(zhuān)題
表格 5.1 一些基本類(lèi)型
 
除了String歸于java.lang包之外,其余所有的基本類(lèi)型都是包scala的成員。 如,Int的全名是scala.Int。然而,由于包scala和java.lang的所有成員都被每個(gè)Scala源文件自動(dòng)引用,你可以在任何地方只用簡(jiǎn)化名(就是說(shuō),像Boolean,或Char,或String這樣的名字)。
注意
目前實(shí)際上你可以使用與Java的原始類(lèi)型相一致的Scala值類(lèi)型的小寫(xiě)化名。比如,Scala程序里你可以用int替代Int。但請(qǐng)記住它們都是一回事:scala.Int。Scala社區(qū)實(shí)踐提出的推薦風(fēng)格是一直使用大寫(xiě)形式,這也是我們?cè)谶@本書(shū)里做的。為了紀(jì)念這個(gè)社區(qū)推動(dòng)的選擇,將來(lái)Scala的版本可能不再支持乃至移除小寫(xiě)變體,因此跟隨社區(qū)的大流,在你的Scala代碼中使用Int而非int才是明智之舉。
敏銳的Java開(kāi)發(fā)者會(huì)注意到Scala的基本類(lèi)型與Java的對(duì)應(yīng)類(lèi)型范圍完全一樣。這讓Scala編譯器能直接把Scala的值類(lèi)型:value type實(shí)例,如Int或Double,在它產(chǎn)生的字節(jié)碼里轉(zhuǎn)譯成Java原始類(lèi)型。
文本
所有在表5.1里列出的基本類(lèi)型都可以寫(xiě)成文本:literal。文本是直接在代碼里寫(xiě)常量值的一種方式。
整數(shù)文本
類(lèi)型Int,Long,Short和Byte的整數(shù)文本有三種格式:十進(jìn)制,十六進(jìn)制和八進(jìn)制。整數(shù)文本的開(kāi)頭方式說(shuō)明了數(shù)字的基。如果數(shù)開(kāi)始于0x或0X,那它是十六進(jìn)制(基于16),并且可能包含從0到9,及大寫(xiě)或小寫(xiě)的從A到F的數(shù)字。舉例如下:
請(qǐng)注意,不論你用什么形式的整數(shù)文本初始化,Scala的shell始終打印輸出基于10的整數(shù)值。因此解釋器會(huì)把你用文本0x00FF初始化的hex2變量的值顯示為十進(jìn)制的255。(當(dāng)然,你也可以不采信我們的話。開(kāi)始感受語(yǔ)言的好方法是你一邊讀本章的時(shí)候一邊在解釋器里試試這些語(yǔ)句。)如果數(shù)開(kāi)始于零,就是八進(jìn)制(基于8)的,并且只可以包含數(shù)字0到7。下面是一些例子:
- scala> val hex = 0x5
 - hex: Int = 5
 - scala> val hex2 = 0x00FF
 - hex2: Int = 255
 - scala> val magic = 0xcafebabe
 - magic: Int = -889275714
 
如果數(shù)開(kāi)始于非零數(shù)字,并且沒(méi)有被修飾過(guò),就是十進(jìn)制(基于10)的。例如:
- scala> val oct = 035 // (八進(jìn)制35是十進(jìn)制29)
 - oct: Int = 29
 - scala> val nov = 0777
 - nov: Int = 511
 - scala> val dec = 0321
 - dec: Int = 209
 
如果整數(shù)文本結(jié)束于L或者l,就是Long類(lèi)型,否則就是Int類(lèi)型。一些Long類(lèi)型的整數(shù)文本有:
- scala> val dec1 = 31
 - dec1: Int = 31
 - scala> val dec2 = 255
 - dec2: Int = 255
 - scala> val dec3 = 20
 - dec3: Int = 20
 
如果Int類(lèi)型的文本被賦值給Short或者Byte類(lèi)型的變量,文本就會(huì)被看作是能讓文本值在那個(gè)類(lèi)型有效范圍內(nèi)那么長(zhǎng)的Short或者Byte類(lèi)型。如:
- scala> val prog = 0XCAFEBABEL
 - prog: Long = 3405691582
 - scala> val tower = 35L
 - tower: Long = 35
 - scala> val of = 31l
 - of: Long = 31
 
浮點(diǎn)數(shù)文本
- scala> val little: Short = 367
 - little: Short = 367
 - scala> val littler: Byte = 38
 - littler: Byte = 38
 
浮點(diǎn)數(shù)文本是由十進(jìn)制數(shù)字,可選的小數(shù)點(diǎn)和可選的E或e及指數(shù)部分組成的。下面是一些浮點(diǎn)數(shù)文本的例子:
請(qǐng)注意指數(shù)部分表示的是乘上以10為底的冪次數(shù)。因此,1.2345e1就是1.2345乘以101,等于12.345。如果浮點(diǎn)數(shù)文本以F或f結(jié)束,就是Float類(lèi)型的,否則就是Double類(lèi)型的。可選的,Double浮點(diǎn)數(shù)文本也可以D或d結(jié)尾。Float文本舉例如下:
- scala> val big = 1.2345
 - big: Double = 1.2345
 - scala> val bigger = 1.2345e1
 - bigger: Double = 12.345
 - scala> val biggerStill = 123E45
 - biggerStill: Double = 1.23E47
 
***一個(gè)值可以用以下(或其他)格式表示為Double類(lèi)型:
- scala> val little = 1.2345F
 - little: Float = 1.2345
 - scala> val littleBigger = 3e5f
 - littleBigger: Float = 300000.0
 
字符文本
- scala> val anotherDouble = 3e5
 - anotherDouble: Double = 300000.0
 - scala> val yetAnother = 3e5D
 - yetAnother: Double = 300000.0
 
字符文本可以是在單引號(hào)之間的任何Unicode字符,如:
除了在單引號(hào)之間顯式地提供字符之外,你還可以提供一個(gè)表示字符代碼點(diǎn)的前綴反斜杠的八進(jìn)制或者十六進(jìn)制數(shù)字。八進(jìn)制數(shù)必須在'\0'和'\377'之間。例如字母A的Unicode字符代碼點(diǎn)是八進(jìn)制101。因此:
- scala> val a = 'A'
 - a: Char = A
 
字符文本同樣可以以前綴\u的四位十六進(jìn)制數(shù)字的通用Unicode字符方式給出,如:
- scala> val c = '\101'
 - c: Char = A
 
實(shí)際上,這種unicode字符可以出現(xiàn)在Scala程序的任何地方。例如你可以這樣寫(xiě)一個(gè)標(biāo)識(shí)符:
- scala> val d = '\u0041'
 - d: Char = A
 - scala> val f = '\u0044'
 - f: Char = D
 
- scala> val B\u0041\u0044 = 1
 - BAD: Int = 1
 
這個(gè)標(biāo)識(shí)符被當(dāng)作BAD,上面代碼里的兩個(gè)unicode字符擴(kuò)展之后的結(jié)果。通常,這樣命名標(biāo)識(shí)符是個(gè)壞主意,因?yàn)樗y讀。然而,這種語(yǔ)法能夠允許含非ASCII的Unicode字符的Scala源文件用ASCII來(lái)代表。
表格 5.2 特殊字符文本轉(zhuǎn)義序列
   
最終,還有一些字符文本被表示成特殊的轉(zhuǎn)義序列,參見(jiàn)表格5.2。例如:
字串文本 字串文本由雙引號(hào)(")環(huán)繞的字符組成:
- scala> val backslash = '\\'
 - backslash: Char = \
 
引號(hào)內(nèi)的字符語(yǔ)法與字符文本相同,如:
- scala> val hello = "hello"
 - hello: java.lang.String = hello
 
由于這種語(yǔ)法對(duì)于包含大量轉(zhuǎn)義序列或跨越若干行的字串很笨拙。因此Scala為原始字串:raw String引入了一種特殊的語(yǔ)法。以同一行里的三個(gè)引號(hào)(""")開(kāi)始和結(jié)束一條原始字串。內(nèi)部的原始字串可以包含無(wú)論何種任意字符,包括新行,引號(hào)和特殊字符,當(dāng)然同一行的三個(gè)引號(hào)除外。舉例來(lái)說(shuō),下面的程序使用了原始字串打印輸出一條消息:
- scala> val escapes = "\\\"\'"
 - escapes: java.lang.String = \"'
 
運(yùn)行這段代碼不會(huì)產(chǎn)生完全符合所需的東西,而是:
- println("""Welcome to Ultamix 3000.
 - Type "HELP" for help.""")
 
原因是第二行前導(dǎo)的空格被包含在了字串里。為了解決這個(gè)常見(jiàn)情況,字串類(lèi)引入了stripMargin方法。使用的方式是,把管道符號(hào)(|)放在每行前面,然后在整個(gè)字串上調(diào)用stripMargin:
- Welcome to Ultamix 3000.
 - Type "HELP" for help.
 
這樣,輸出結(jié)果就令人滿意了:
- println("""|Welcome to Ultamix 3000.
 - |Type "HELP" for help.""".stripMargin)
 
符號(hào)文本
- Welcome to Ultamix 3000.
 - Type "HELP" for help.
 
符號(hào)文本被寫(xiě)成'< 標(biāo)識(shí)符>,這里< 標(biāo)識(shí)符>可以是任何字母或數(shù)字的標(biāo)識(shí)符。這種文本被映射成預(yù)定義類(lèi)scala.Symbol的實(shí)例。特別是,文本'cymbal將被編譯器擴(kuò)展為工廠方法調(diào)用:Symbol("cymbal")。符號(hào)文本典型的應(yīng)用場(chǎng)景是你在動(dòng)態(tài)類(lèi)型語(yǔ)言中使用一個(gè)標(biāo)識(shí)符。比方說(shuō),或許想要定義個(gè)更新數(shù)據(jù)庫(kù)記錄的方法:
方法帶了一個(gè)符號(hào)參數(shù)指明記錄的字段名和一個(gè)字段應(yīng)該更新進(jìn)記錄的值。在動(dòng)態(tài)類(lèi)型語(yǔ)言中,你可以通過(guò)傳入一個(gè)未聲明的字段標(biāo)識(shí)符給方法調(diào)用這個(gè)操作,但Scala里這樣會(huì)編譯不過(guò):
- scala> def updateRecordByName(r: Symbol, value: Any) {
 - // code goes here
 - }
 - updateRecordByName: (Symbol,Any)Unit
 
基本同樣簡(jiǎn)潔的替代方案是,你可以傳遞一個(gè)符號(hào)文本:
- scala> updateRecordByName(favoriteAlbum, "OK Computer")
 - < console>:6: error: not found: value favoriteAlbum
 - updateRecordByName(favoriteAlbum, "OK Computer")
 
除了發(fā)現(xiàn)它的名字之外,沒(méi)有太多能對(duì)符號(hào)做的事情:
- scala> updateRecordByName('favoriteAlbum, "OK Computer")
 
另一件值得注意的事情是符號(hào)是被拘禁:interned的。如果你把同一個(gè)符號(hào)文本寫(xiě)兩次,那么兩個(gè)表達(dá)式將指向同一個(gè)Symbol對(duì)象。
- scala> val s = 'aSymbol
 - s: Symbol = 'aSymbol
 - scala> s.name
 - res20: String = aSymbol
 
布爾型文本
布爾類(lèi)型有兩個(gè)文本,true和false:
- scala> val bool = true
 - bool: Boolean = true
 - scala> val fool = false
 - fool: Boolean = false
 
【相關(guān)閱讀】















 
 
 
 
 
 
 