1.hello world程序
object HelloWorld { def main(args: Array[String]) { println("Hello,World!") } }
注意
語句末尾的分號通常是可選的。
語句末尾的分號通常是可選的。
分號是表達式分隔符,它們是推斷的。
Scala將行的結尾視為表達式的結尾,除非它可以推斷表達式繼續到下一行。
Scala程序處理從主方法開始,這是每個Scala程序的一個強制性部分。
主要方法未標記為靜態。
主要方法是對自動實例化的單例對象的實例方法。
沒有返回類型。實際上有Unit,這是類似於void,但它是由編譯器推斷。
我們可以通過在參數后面加一個冒號和類型來顯式地指定返回類型:
def main(args: Array[String]) : Unit = { }
Scala使用def
關鍵字告訴編譯器這是一個方法。
在Scala中沒有訪問級別修改器。
Scala未指定公用修飾符,因為默認訪問級別為public。
Scala變量
在Scala中,有三種方法可以定義變量:val,var和延遲 val。
Scala允許您在聲明它時決定變量是否是不可變的(只讀)
val
使用關鍵字val
聲明不可變變量。
這意味着它是一個不能更改的變量。
var
現在讓我們聲明一個可變變量。
一個可變變量用關鍵字var
來聲明:
延遲val
延遲val變量計算一次,第一次訪問變量。只有vals可以是惰性變量。
Scala 代碼塊
方法和變量定義可以是如下的單行:
def meth() = "Hello World"
方法和變量也可以在用大括號{}表示的代碼塊中定義。
代碼塊可以嵌套。
代碼塊的結果是在代碼塊中計算的最后一行,如以下示例所示。
object Main {
def meth1():String = {"hi"}
def meth2():String = {
val d = new java.util.Date() d.toString() } def main(args: Array[String]) { println(meth1 ) println(meth2 ) } }
變量定義也可以是代碼塊。
val x3:String= { val d = new java.util.Date() d.toString() }
Scala 注釋
Scala注釋很像Java和C ++注釋。
多行注釋以/*開頭,以*/結束。
/* This is a multiline comment: */
單行注釋用//開頭,並繼續到行尾:
// This is a single line comment
在Scala中,我們可以嵌套多行注釋:
/* This is an outer comment /* And this comment is nested */ Outer comment */
Scala 布爾類型
val x = !false
Scala字符類型
字符常量用單引號編寫,區別於使用雙引號寫的字符串常量。
Scala字符串
Scala的String構建在Java的String上,並向Java的String添加了字符串插值等附加功能。
字符串插值
字符串插值是一種將字符串中的值與變量組合的機制。
Scala中的插值符號是在字符串的第一個雙引號之前添加的s
前綴。
然后可以使用美元符號運算符$
引用變量。
以下代碼說明了字符串插值的用法。
object Main {
def main(args: Array[String]) {
val bookTitle = "Scala" // creating a String
// String interpolation
println(s"Book Title is ${ bookTitle}" ); } }
Scala數字類型
Scala中的數字數據類型構成了Float和Double類型以及諸如Byte,Short,Int,Long和Char等整數數據類型。
下表顯示Scala的數值數據類型。
數據類型 | 描述 |
---|---|
Byte | 從-128到127范圍內的整數 |
Short | 從-32768到32767范圍內的整數 |
Int | 從-2147483648到2147483647范圍內的整數 |
Long | 從-9223372036854775808到9223372036854775807范圍內的整數 |
Float | 最大正有限浮點是3.4028235 * 1038,最小正有限非零浮點是1.40 * 10-45 |
Double | 最大正有限雙是1.7976931348623157 * 10308,最小正有限非零雙是4.9 * 10-324 |
例子
Scala可以按順序自動將數字從一種類型轉換為另一種類型。
Byte . Short . Int . Long . Float . Double.
其中字節類型是最低的,並且可以轉換為任何其他類型,如以下示例所示:
val x: Byte = 30
我們可以將x賦值為Short類型,如下例所示:
val y: Short = x
同樣,我們可以將x賦值為Int,Long,Float,Double,Scala會自動轉換數字,如下例所示:
val z: Double = y
Scala不允許以前面提到的順序自動轉換。
Scala常量值
整數常量
整數常量可以用十進制,十六進制或八進制表示。
詳細總結在下表中。
類型 | 格式 | 例子 |
---|---|---|
Decimal | 0或非零數字后跟零或多個數字(0-9) | 0, 1, 321 |
Hexadecimal | 0x后跟一個或多個十六進制數字(0-9,A-F,a-f) | 0xFF, 0x1a3b |
Octal | 0后跟一個或多個八進制數字(0-7)a | 013, 077 |
截至Scala 2.10,一個八進制常量已被棄用。
您可以通過在常量前添加一個-
號來表示負數。
對於長文本,需要在文本末尾附加L
或l
字符,除非將值分配給聲明為Long的變量。
否則,推斷Int。
整數字符串的有效值受要為其分配值的變量的類型的限制。
下表定義了包含的限制。
目標類型 | 最低(含) | 最大(包括) |
---|---|---|
Long | -263 | 263 |
Int | -231 | 231 - 1 |
Short | -215 | 215 |
Char | 0 | 216 |
Byte | -27 | 27 - 1 |
如果指定的整數常量數超出這些范圍,則會發生編譯時錯誤。
浮點常量
浮點常量是帶有可選減號,零個或多個數字,后跟句點.
,后跟一個或多個數字的表達式。
對於Float
常量,在文字末尾附加F
或f
字符。否則,假定為Double。
我們可以選擇為D加上D
或d
。
浮點常量可以用或不用指數表示。
指數部分的格式為e或E,后跟可選的+或 - ,后跟一個或多個數字。
這里有一些浮點常量的例子。 Double被推斷除非聲明的變量是Float或使用f或F后綴:
.14 3.14 3.14f 3.14F 3.14d 3.14D 3e5 3E5 3.14e+5 3.14e-5 3.14e-5 3.14e-5f 3.14e-5F 3.14e-5d 3.14e-5D
布爾常量
布爾常量是true
和false
。
它們被分配到的變量的類型將被推斷為布爾值:
object Main { def main(args: Array[String]) { val b1 = true val b2 = false println(b1); println(b2); } }
字符常量
字符常量是可打印的Unicode字符或轉義序列,寫在單引號之間。
Unicode值介於0和255之間的字符可以由八進制轉義表示,即反斜杠(\)后跟最多三個八進制字符的序列。
這里有些例子:
"A" "\u0041" // "A" in Unicode "\n" "\012" // "\n" in octal "\t"
有效的轉義序列如下表所示。
序列 | 含義 |
---|---|
\b | 退格(BS) |
\t | 水平制表(HT) |
\n | 換行(LT) |
\f | 換頁(FF) |
\r | 回車(CR)... |
\" | 雙引號(“) |
\" | 單引號(“) |
\\ | 反斜杠(\) |
字符串常量
字符串常量是用雙引號或三重雙引號括起來的字符序列,即“”“...”“”。
對於雙引號中的字符串字符,允許的字符與字符常量相同。
要在字符串中包含雙引號“
字符,必須使用\
字符“轉義"。
這里有些例子:
"This is a\ntest" "He said, \"SQL is for database!\"" "First\tSecond"
由雙引號的三元組界定的字符串常量稱為多行字符串常量。
這些字符串可以覆蓋幾行。換行符將是字符串的一部分。它們可以包括任何字符,包括一個或兩個雙引號在一起,但不能三個在一起。
它們對於不具有有效Unicode或轉義序列的\字符的字符串非常有用。
這里有三個示例字符串:
"""This is a \ntest""" """He said, "SQL is for database!" """ """First line\n Second line\t Fourth line"""
在代碼中使用多行字符串時,要使用String.stripMargin縮進子字符串以進行正確的代碼格式化。
它刪除子字符串中的所有空格,直到並包括垂直條|
的第一次出現。
要添加空格縮進,請將空格放在|
后面。
考慮這個例子:
object Main {
def main(args: Array[String]) {
println(hello("This is a test") );
}
def hello(name: String) = s"""Welcome! Hello, $name! * (Star!!) |Hi. | whitespace.""" .stripMargin }
要使用不同於|
的前導字符,請使用帶有Char(字符)參數的stripMargin的重載版本。
如果整個字符串都有要刪除的前綴或后綴,則有相應的前綴和stripSuffix方法。
object Main {
def main(args: Array[String]) {
println(goodbye("www.w3cschool.cn"));
}
def goodbye(name: String) =
s"""xxxGoodbye, ${name}yyy xxxCome again!yyy""" .stripPrefix("xxx").stripSuffix("yyy") }
符號常量
Scala有符號類型,它們是內部連接的字符串,意味着具有相同“名稱”的兩個符號實際上是指內存中的同一個對象。
符號常量是單引號'
,后跟一個或多個數字,字母或下划線(“_”),但第一個字符不能是數字。
函數常量
(i:Int,s:String)=>
s + i 是Function2類型的函數文本[Int,String,String](返回String)。
你甚至可以使用常量語法作為類型聲明。
以下聲明是等效的:
val f1: (Int,String) => String = (i, s) => s+i val f2: Function2[Int,String,String] = (i, s) => s+i
元組常量
Scala庫包括用於將N個項分組的TupleN類(例如,Tuple2),以及括號內的項的逗號分隔列表的文字語法。
對於1到22之間的N,有單獨的TupleN類。
例如,val tup =(“Hi”,2014)定義了一個Tuple2實例,其中第一個元素推斷String,第二個元素Int推斷。
Tuple實例是不可變的,第一類值,因此您可以將它們分配給變量,將它們作為值傳遞,並從方法中返回。
我們還可以使用常量語法為Tuple類型聲明:
val t1: (Int,String) = (1, "two") val t2: Tuple2[Int,String] = (1, "two")
以下示例演示使用元組:
object Main {
def main(args: Array[String]) {
val t = ("Hello", 1, 2.3)
println( "Print the whole tuple: " + t ) println( "Print the first item: " + t._1 ) println( "Print the second item: " + t._2 ) println( "Print the third item: " + t._3 ) val (t1, t2, t3) = ("World", "!", 0x22) println( t1 + ", " + t2 + ", " + t3 ) val (t4, t5, t6) = Tuple3("World", "!", 0x22) println( t4 + ", " + t5 + ", " + t6 ) } }
表達式t._n從元組t中檢索第n個項,從一個開始,不是零,遵循歷史約定。
有幾種方法來定義兩元素元組,有時稱為一對。
我們可以在兩個值之間使用“箭頭運算符”,以及在元組相關類上使用特殊的工廠方法:
(1, "one") 1 -> "one" Tuple2(1, "one")
Scala Nothing和Null類型
Null是所有引用類型的子類型。它是所有AnyRef類型的子類型,為關鍵字null提供類型。
Scala沒有null關鍵字。
例如,不可能為scala.Int類型的變量分配null。
對於影響程序流程的操作,沒有任何提供兼容的返回類型。
Nothing的用法之一是它發出異常終止的信號。
任何時候,如果你想使用null
,請改用Option
。
Scala選項
Option
允許我們在沒有null“hack”的情況下顯式地表達空值。
Option是一個抽象類,它的兩個具體子類是Some,當我們有一個值,而None,當我們沒有。
例子
您可以在以下示例中查看選項,一些和無操作,其中我們在美國創建州首府地圖:
object Main {
def main(args: Array[String]) {
val stateCapitals = Map(
"Alabama" -> "Montgomery", "Alaska" -> "Juneau", "Wyoming" -> "Cheyenne") println( "Get the capitals wrapped in Options:" ) println( "Alabama: " + stateCapitals.get("Alabama") ) println( "Wyoming: " + stateCapitals.get("Wyoming") ) println( "Unknown: " + stateCapitals.get("Unknown") ) println( "Get the capitals themselves out of the Options:" ) println( "Alabama: " + stateCapitals.get("Alabama").get ) println( "Wyoming: " + stateCapitals.get("Wyoming").getOrElse("Oops!") ) println( "Unknown: " + stateCapitals.get("Unknown").getOrElse("Oops2!") ) } }
注意
Map.get方法返回一個Option [T]
,在這種情況下T
是String。
通過返回一個選項,我們不能“忘記”我們必須驗證返回的東西。
如果Option
是Some
,則Some.get
返回值。
如果Option
實際上是None
,那么None.get
將拋出一個NoSuchElementException
異常。
在最后兩個println語句中的getOrElse
返回Option
中的值,如果它是一個Some
實例,或者返回傳遞給getOrElse
的參數,如果它是一個None
實例。
getOrElse
參數作為默認返回值。
Scala范圍
有些代碼需要從一些開始到結束創建一個數字序列。一個Range
常量量是我們需要的。
范圍可以通過它們的開始,結束和步進值來定義。
要在Scala中創建范圍,請使用預定義的方法,如以下代碼所示:
object Main { def main(args: Array[String]) { println(1 to 5 ) } }
我們還可以使用預定義的方法創建一個具有上限(不包括其上限)的范圍,直到如下代碼所示。
object Main { def main(args: Array[String]) { println(1 until 5 ) } }
對於1到5,創建范圍(1,2,3,4,5),但對於1到5,創建具有上限獨占范圍(1,2,3,4)的范圍。
我們還可以使用預定義的方法創建一個帶有步進值的范圍,如下面的代碼所示。
object Main { def main(args: Array[String]) { println(1 to 20 by 4 ) } }
例子
以下示例顯示如何為支持它們的類型創建范圍:Int,Long,Float,Double,Char,BigInt和BigDecimal。
object Main {
def main(args: Array[String]) {
var v = 1 to 10 // Int range inclusive, interval of 1, (1 to 10)
println(v)
v = 1 until 10 // Int range exclusive, interval of 1, (1 to 9)
println(v)
val v1 = 1 to 10 by 3 // Int range inclusive, every third.
println(v1)
val v2 = 10 to 1 by -3 // Int range inclusive, every third, counting down.
println(v2)
val v3 = 1L to 10L by 3 // Long
println(v3)
val v4 = 1.1f to 10.3f by 3.1f // Float with an interval != 1
println(v4)
val v5 = 1.1f to 10.3f by 0.5f // Float with an interval < 1
println(v5)
val v6 = 1.1 to 10.3 by 3.1 // Double
println(v6)
val v7 = "a" to "g " by 3 // Char println(v7) val v8 = BigInt(1) to BigInt(10) by 3 println(v8) val v9 = BigDecimal(1.1) to BigDecimal(10.3) by 3.1 println(v9) } }
注意
您可以創建包含或獨占上限的范圍,並且您可以指定不等於1的間隔:
Scala元組
元組是具有相同或不同類型的兩個或更多個值的有序容器。
然而,與列表和數組不同,沒有辦法迭代元組中的元素。
它的目的只是作為一個多個值的容器。
元組在需要組合離散元素並提供結構化數據的通用方法時非常有用。
我們可以通過兩種方式創建一個元組:
- 通過用逗號分隔的值寫入值,並用一對括號括起來
- 通過使用關系運算符
->
例子
以下代碼顯示了一個包含Int,一個布爾值和一個String的元組,使用前一個方法。
val tuple = (1, false, "Scala")
以下代碼顯示了使用關系運算符創建的元組:
val tuple2 ="title" -> "Beginning Scala"
元組的單個元素可以通過其索引訪問,其中第一個元素具有索引1。
以下代碼顯示了訪問元組的第三個元素。
val tuple = (1, false, "Scala") val third = tuple._3
Scala單元類型
單元類型用於定義不返回數據的函數。它類似於Java中的void關鍵字。
例子
以下代碼定義了具有單元類型的主方法。
def main(args: Array[String]) : Unit = { }
單元常量是一對空圓括號, ()。
附錄
import org.apache.spark.SparkConf; import org.apache.spark.SparkContext; //定義一個類Person(屬性,方法) class Person(val name: String, var age: Int) object base { //定義一個無返回值的方法 def func(s:String):Unit={ println(s) } def meth() = "Hello World" //單行方法代碼塊 def meth1():String = {"hi"} //返回值為String的方法代碼塊 def meth2():String = { //具體的函數體實現(代碼塊) val d = new java.util.Date() d.toString() } //刪除前綴和后綴 def goodbye(name: String) = s"""xxxGoodbye, ${name}yyy xxxCome again!yyy""" .stripPrefix("xxx").stripSuffix("yyy") //主方法:Unit相當於void,無返回值類型 def main(args: Array[String]): Unit = { //System.setProperty("hadoop.home.dir", "D:\\hadoop");//設置hadoop環境 //val conf = new SparkConf().setAppName("Base").setMaster("spark://192.168.66.66:7077");//加載spark遠程作業調度 //val spark=new SparkContext(conf);//聲明一個sparkContext上下文 val data = Array(1, 2, 3, 4, 5); //定義一個不可變數組 func("hello");//調用方法 println(data(1))//輸出單個數組元素 //遍歷輸出data數組 for (i<-data) { println(i) } //spark.stop(); for(i<- 1 to 10){ println(i) } for { i <- 1 to 10 j <- 1 to 10 } println(i* j) val p = new Person("Dean Wampler", 29) //聲明一個類對象 println(p.name) //調用並輸出類屬性 println(p.age ) p.age = 30 println(p.age ) println(meth+"\n"+meth1()+"\n"+meth2())//函數調用無參數不需要帶() /*定義一個不可變且返回值為String的代碼塊*/ val x3:String= { val d = new java.util.Date() d.toString() } println(x3) val x = !false //布爾類型 var xf=true //布爾型常量 val y='1' //單引號的字符常量 val z="scala" //雙引號的字符串常量 val zx:String="spark" println(xf+""+x+"-"+y+s"-${z}"+"-"+zx) //s"-${z}"字符串插值 val xx: Byte = 30 //數字類型Byte . Short . Int . Long . Float . Double. val yy: Short = xx val zz: Double = yy println(xx+"-"+yy+"-"+zz) println(goodbye("www.w3cschool.cn")); //函數常量定義 val f1: (Int,String) => String = (i, s) => s+i //返回值為String val f2: Function2[Int,String,String] = (i, s) => s+i //前兩個為參數,后一個為返回值 println(f1(1,"name")+"-"+f2(1,"siat")) //元組常量 //val t1: (Int,String) = (1, "two") //val t2: Tuple2[Int,String] = (1, "two") val t = ("Hello", 1, 2.3) //定義一個元組 println( "Print the whole tuple: " + t ) //輸出整個元組 println( "Print the first item: " + t._1 ) //輸出第一個元組元素 println( "Print the second item: " + t._2 ) //輸出第二個元組元素 println( "Print the third item: " + t._3 ) //輸出第三個元組元素 //定義三個元組,每個元組存儲一個元素 val (t1, t2, t3) = ("World", "!", 0x22) println( t1 + ", " + t2 + ", " + t3 ) val (t4, t5, t6) = Tuple3("World", "!", 0x22) println( t4 + ", " + t5 + ", " + t6 ) //Scala沒有null關鍵字 //范圍Range println(1 to 5 ) //包括上限1,2,3,4,5 println(1 until 5 ) //不包括上限1,2,3,4 println(1 to 20 by 4 ) //從1到20每次進四個值包括下限1 val v2 = 10 to 1 by -3 //Int val v3 = 1L to 10L by 3 //Long val v4 = 1.1f to 10.3f by 3.1f //Float val v5 = 1.1f to 10.3f by 0.5f val v6 = 1.1 to 10.3 by 3.1 //Double val v7 = 'a' to 'g' by 3 //Char val v8 = BigInt(1) to BigInt(10) by 3 val v9 = BigDecimal(1.1) to BigDecimal(10.3) by 3.1 println(v2+"-"+v3+"-"+v4+""+v5+""+v6+""+v7+""+v8+""+v9) val tuple = (1, false, "Scala") val tuple2 ="title" -> "Beginning Scala" val third = tuple._3 println(tuple._2+"-"+tuple2._1+"-"+third) //Unit單元類型用於定義不返回數據的函數。它類似於Java中的void關鍵字。 } }