Scala入門 【1】 轉載請註明出處: "http://www.cnblogs.com/BYRans/" 1 基礎 val定義的為常量,var為變數 val name:Type = ,變數名後加冒號,然後定義變數類型 Scala有7種 數值類型 :Byte、Char、Short、Int、Long、 ...
Scala入門 【1】
轉載請註明出處:http://www.cnblogs.com/BYRans/
1 基礎
- val定義的為常量,var為變數
- val name:Type = ***,變數名後加冒號,然後定義變數類型
- Scala有7種數值類型:Byte、Char、Short、Int、Long、Float和Double,以及一個Boolen類型。
Scala支持語法:
a 方法 b
,或者簡寫為:a.方法(b)
例如:
產出1 to 10 或者 1.to(10)
Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
- Scala沒有
++
和--
操作,需要使用+=1
和-=1
不帶參數的Scala方法通常不使用圓括弧。例如:
"Hello".distinct
輸出"Helo"
2 控制結構和函數
- 概述
- if表達式有值
- 塊也有值——是它最後一個表達式的值
- Scala的for迴圈就像是“增強版”的java for迴圈
- 分號(在絕大多數情況下——不是必需的
- void類型是Unit
- 避免在函數定義中使用return
- 註意別在函數式定義中漏掉了=
- 異常的工作方式和java或C++中基本一樣,不同的是你在catch語句中使用“模式匹配”
Scala沒有受檢異常
if語句
if (3 > 22) "asdf" else ()
類似於java/c++中的?:
,在Scala中if/else
和?:
結合在了一起。在這個例子中,兩個分支有一個公共超類Any
。如果if語句不需要else,可以寫為if(x>1) ()
輸出為Unit = ()
。
換行
Scala程式結尾不需要加
;
,當然,如果加爺可以。如果一行代碼太長,必須要寫為兩行,要確保第一行以一個不能用作語句結尾的符號結尾,通常為操作符,例如:s = s0 + (v - v0) * t + // +告訴解析器這裡不是語句的末尾 0.5 * (a - a0) * t * t
控制台輸入輸出
scala輸出語法:
print("輸出無換行") println("輸出加換行") printf("Hello,%s. You are %d years old.\n","Rans",27) // C風格輸出
readLine方法可以從控制台讀取一行輸入。如果要讀取數字、Boolean或字元,可以用readInt、readDouble、readByte、readShort、readLong、readFloat、readBoolean、readChar。這些方法中,只有readLine方法有參數:
val name = readLine("Your name: ") print("Your age: ") val age = readInt() println("Hello " + name + ", Next year you will be " + (age + 1) )
for迴圈
- Scala的while迴圈與java/C++的相同,但Scala沒有
for(int i=0;i < 10;i++)
這種迴圈語句,如果要使用這種語句有兩種選擇:- 一是使用while迴圈;
- 二是使用語法
for(i <- 表達式)
,語法表示讓變數i遍歷<-
右邊的表達式的所有值。例如:
在for迴圈的變數之前沒有val或var的指定。該變數的類型是集合的元素類型。迴圈變數的作用域一直持續到迴圈結束。for(i <- 1 to n) r = r * i
在遍歷字元串或數組時,可以用
until
方法而不是to
方法,until
方法返回不包含上限的區間。val s = "Hello" var sum = 0 for (i <- 0 until s.length) // i的最後一個取值是s.length-1 sum += s(i)
對字元串的遍歷可直接使用:
var sum = 0 for (ch <- "Hello") sum += ch
- Scala中沒有提供
break
和continue
語句來退出迴圈,當然,也有方法實現這個功能,但是最好避免使用這種方式。 高級for迴圈和for推導式:
for(i <- 1 to 3;j <- 1 to 3) print ((10 * i + j) + " ") // 列印11 12 13 21 22 23 31 32 33 for(i <- 1 to 3;j <- 1 to 3 if i != j) print ((10 * i + j) + " ") // 列印12 13 21 23 31 32 for(i <- 1 to 3;from = <- 1 to 3 if i != j) print ((10 * i + j) + " ") // 列印12 13 21 23 31 32 for(i <- 1 to 10) yield i % 3 // 生成Vector(1,2,0,1,2,0,1,2,0,1)
函數定義
定義函數需要指明函數的名稱、參數(包括參數的類型)和函數體,只要函數不是遞歸的,就不需要指定返回類型,例如:
def abs(x: Double) = if (x >= 0) x else -x
如果函數體需要多個表達式,可以使用代碼塊。代碼塊中最後一個表達式的值就是函數的返回值,例如下麵代碼中
r
值即為函數的返回值:def fac(n: Int) = { var r = 1 for (i <- 1 to n) r = r * i r
遞歸函數需要指明返回類型,示例:
def fac(n: Int): Int = if (n <= 0) 1 else n * fac(n - 1)
參數參數和帶名參數
預設函數參數和帶名參數,例如下麵函數有3個參數,其中
left
和right
兩個參數有預設值。在調用該函數時,如果沒有指定預設參數的值,那麼預設參數將使用預設值。def decorate(str: String, left: String = "[", right: String = "]") = left + str + right decorate("Hello") // 得到 [Hello] decorate("Hello","<<<",">>>") // 得到 <<<Hello>>> decorate("Hello","<<<") // 得到 <<<Hello] decorate("Hello",rigth = ">>>") // 得到 [Hello>>> decorate(left = "<<<", str = "Hello", right = ">>>") // 得到 <<<Hello>>>
變長參數
如下函數的參數個數是可變的,可以用任意個參數調用該函數,這多個參數在函數內部是一個
Seq
類型的參數:def sum(args: Int*) = { var result = 0 for (arg <- args) result += arg result } val s = sum(1,2,3,4) // 得到 s: Int = 10 val s = sum(1 to 4) // 錯誤!! val s = sum(1 to 4: _*) // 如果傳入的是一個區間,需要追加:_*
3 數組相關操作
定長數組
Scala中定長數組為
Array
,示例如下:val nums = new Array[Int](10) // 10個整數類型的數組,所有元素初始化為0 val a = new Array[String](10) // 10個元素的字元串數組,所有元素初始化為null val s = Array("Hello","World") // 已提供初始值就不需要new關鍵詞,也不需要指明類型,類型Scala會自動推斷 s(0) = "Goodbye" // Array("Goodbye","World"),使用()訪問元素,註意不是使用[]
變長數組
ArrayBuffer
變長數組(數組緩衝)的長度可以變化,類似於java中的ArrayList。示例如下:import scala.collection.mutable.ArrayBuffer val b = new ArrayBuffer[Int]() // 創建ArrayBuffer,可以不寫new關鍵詞 b += 1 // ArrayBuffer(1),用 += 在末尾添加元素 b += (2,3,4) // ArrayBuffer(1,2,3,4),用 += 可添加多個元素,多個元素用括弧包起來 b ++= Array(5,6,7) // ArrayBuffer(1,2,3,4,5,6,7),用 ++= 操作追加集合 b.trimEnd(5) // ArrayBuffer(1,2),移除最後5個元素
遍歷
在for迴圈中如果不需要元素的下標,可以如下遍歷:
for (elem <- a) println(elem)
在for迴圈中如果需要用到元素下標,可以如下遍歷:
for (i <- 0 until a.length) // until產生0到length-1之間的數 println(i + ": " + a(i)) (0 until a.length).reverse // 倒序產生區間,得到Range(...,2,1,0)
數組轉換
基於數組或數組緩衝,構建新的數組或數組緩衝。使用
for (elem <- arr if ...) ... yield ...
,示例如下:val a = Array(2,3,5) val result = for (elem <- a) yield 2 * elem // 得到Array(4,6,10)。如果a是ArrayBuffer,那麼得到的就是ArrayBuffer // for迴圈中也可以使用守衛,即for中加if val guard = for (elem <- a if elem % 2 == 0) yield 2 * elem // 得到Array(4)
多維數組
Scala和java一樣,多維數組是通過數組內放數組的方式來實現的。構建數組使用
ofDim
方法:val marix = Array.ofDim[Double](3,4) // 構建三行四列的Double類型的數組 // 可以創建不規則的數組,即每行的長度可以不同 val triangle = new Array[Array[Int]](10) for (i <- 0 until triangle.length) triangle(i) = new Array[Int](i + 1)
數組與java互操作
- Scala數組和java數組可以互操作;用ArrayBuffer,使用
scala.collection.JavaConversions
中的轉換函數
4 映射和元組
構造Map
構造Map代碼示例:
val scores = Map("Alice" -> 10,"Bob" -> 3) // 該Map[String,Int]key對應的value不可以修改,也不可以添加新的kv對 val scores = scala.collection.mutable.Map("Alice" -> 10,"Bob" -> 3) // 該Map[String,Int]key對應的value可以修改 val scores = scala.collection.mutable.HashMap[String,Int] //創建空的HashMap
獲取Map的值
可以使用
map(key)
訪問key對應的value,對map可以調用contains
、getOrElse
、get
等方法代碼示例:val bobsScore = scores("Bob") // 如果map中沒有參數指定的key,則會報出異常,在調用前可以使用contains檢查是否存在key val bobsScore = if (scores.contains("Bob")) scores("Bob") else 0 // 可以使用getOrElse方法實現上述功能 val bobsScore = scores.getOrElse("Bob",0)
更新Map中的值
- 使用
+=
添加新的kv對(可以為多個kv對),使用-=
刪除某個key對應的kv對(可以為多個kv對)
遍歷Map
- 可以用
for ((k,v) <- 映射) k和v的處理邏輯
來迭代處理hashmap - 可以用
map.keySet
方法和map.values
方法獲取key和value的集合
元組
- 元組(tuple)是不同類型的值的聚集。例如
(1,3.14,"Fred")
為一個3元組,類型為`Tuple3[Int,Double,java.lang.String] 對於一個元組可以使用方法
_i
(i為從1開始的下標)訪問其組元,例如:val t = (1,3.14,"Fred") val second = t._2 // 得到second: Double = 3.14