快學Scala初級A1整理(1)

Scala是一門有趣且實用的語言,它以JVM位目標環境,將面向對象和函數式編程有機地結合起來,帶來獨特的編程體驗。本文主要整理《快學Scala》中的初級A1部分,適用於Scala的初級應用開發學習。轉載請註明博客原文地址:http://blog.tomgou.xyz/kuai-xue-scalachu...html

0.安裝和運行scala

解壓scala安裝包到任意目錄:java

$ cd /home/tom
$ tar -xzvf scala-2.10.6.tgz
$ sudo vim /etc/profile

/etc/profile文件的末尾添加環境變量:程序員

export SCALA_HOME=/home/tom//scala-2.10.6
export PATH=$SCALA_HOME/bin:$PATH

保存並更新/etc/profile算法

$ source /etc/profil

查看是否成功:shell

$ scala -version

創建一個簡單的scala程序scalatest.scala編程

object scalatest {
  def main(args:Array[String]){
    def box(s:String){
      var border = "-" * s.length + "--\n"
      println(border + "|" + s +"|\n" + border)
    }
    box("Hello Tom!")

  }
}

編譯程序:vim

$  scalac scalatest.scala

執行程序:api

$  scala scalatest

獲得結果:數組

------------
|Hello Tom!|
------------

1.Scala基礎

1.1 Scala解釋器

Scala解釋器讀到一個表達式,對它求值,將其打印,接着再繼續讀下一個表達式。這個過程被稱爲讀取-求值-打印-循環,即REPL。bash

scala> 8 * 5 + 2
res0: Int = 42

從技術上講,scala程序並非一個解釋器。實際發生的過程是,你輸入的內容被快速地編譯成字節碼,而後這段字節碼交由Java虛擬機執行。

REPL在同一時間只能看到一行代碼。
在REPL粘貼成塊代碼,須要鍵入:paste,粘貼代碼塊,而後按下Ctrl+D。

1.2 常量與變量

以val定義常量,以var定義變量:

val answer = 8 * 5 + 2
var counter = 0
counter = 1

在Scala中,咱們鼓勵使用val。同時,你不須要給出值或者變量的類型,這個信息能夠從你初始化它的表達式中判斷出來。必要時,可指定類型,如:

val greeting: String = null

在Scala中,無需分號,僅當同一行代碼中存在多條語句時才用分號分開。

1.3 經常使用類型

和Java同樣,Scala有7種數據類型:
Byte Char Short Int Long Float Double Boolean
跟Java不一樣的是,這些類型是類。你能夠對數字執行方法,如:

1.toString() //產出字符串"1"
1.to(5) //產出Range(1,2,3,4,5)

Scala用底層的java.lang.String類來表示字符串,不過經過StringOps類給字符串追加了上百種操做,好比:

"Hello".intersect("World") //輸出"lo"

Scala還提供了RichInt,RichDouble,RichChar等,提供了Int,Double,Char不具有的便捷方法。好比1.to(10)中,Int值1首先被轉換成RichInt,而後調用to方法。

1.4 算術和操做符重載

+-*/%等操做符其實是方法,好比a+b是以下方法a.+(b)的簡寫。
一般你能夠用a 方法 b來簡寫方法a.方法(b)。好比1.to(5)能夠寫成1 to 5
Scala沒有提供++--操做符,須要使用+=1-=1,如counter += 1

1.5 調用函數和方法

在Scala中使用數學函數比Java簡單,你不須要從某個類調用它的靜態方法。

sqrt(2)
pow(2, 4)//16.0
min(3, Pi)//3.0

這些數學函數在scala.math包中定義,能夠經過如下語句引入:

import scala.math._ //在Scala中,_字符是通配符,相似Java中的*

引入以scala.開頭的包時,能夠省去scala前綴。
不帶參數的Scala方法一般不使用圓括號,如:

"Hello".distinct

1.6 apply方法

"Hello"(4)//將產出'o'

"Hello"(4)是以下方法的簡寫:

"Hello".apply(4)

()操做符能夠做爲apply方法的重載形式,好比說將字符串或數字轉換成BigInt對象的apply方法,BigInt("123")BigInt.apply("123")的簡寫,Array(1,4,9)返回一個數組,用的就是Array伴生對象的apply方法。

1.7 Scaladoc

能夠在http://www.scala-lang.org/api在線瀏覽Scaladoc。

  • 類名旁的O和C分別連接到對應的類(C)和伴生對象(O)

  • 標記爲implicit的方法對應的是自動隱式轉換

  • 方法能夠以函數做爲參數


2.控制流與函數

2.1 條件表達式

Scala中的if/else表達式有值,這個值就是if或else後的值,如:

val s = if (x > 0) 1 else -1

上式將if/else表達式的值賦值給常量。還能夠這樣寫:

if (x > 0) s = 1 else s = -1

不過第一種寫法更好,第二種寫法中,s必須是變量var。

以下是混合類型的條件表達式:

if (x > 0) "positive" else -1

一個分支是String,另外一個是Int,它們的公共超類型叫作Any。

當if語句沒有輸出值時,引入了Unit類,寫作()。以下:

if (x > 0) 1 else ()

()能夠當作是表示「無有用值」的佔位符。

2.2 語句終止

Scala與JavaScript等腳本語言相似,行尾位置不須要分號。
若是你在寫較長的語句,須要分兩行來寫的話,確保第一行以一個不能用做語句結尾的符號結尾,如:

s = s0 + (v - v0) * t +
    0.5 * (a - a0) * t * t

Scala程序員傾向使用Kernighan & Ritchie風格的花括號:

if (n > 0) {
    r = r * n
    n -= 1
}

2.3 塊表達式與賦值

在Scala中,{}塊包含一系列表達式。塊中最後一個表達式的值就是塊的值。如:

val distance = {val dx=x-x0;val dy=y-y0;sqrt(dx*dx+dy*dy)}

賦值動做自己是沒有值的,是Unit類型的。一個以賦值語句結束的塊,好比:{r=r*n;n-=1}的值是Unit類型的。x=y=1//別這樣中,x被賦的值是Unit類型的。

2.4 輸入與輸出

打印:

print("hello")
println(42) //打印內容後會追加一個換行符

格式化字符串的printf:

printf(" %s is %d years old.\n","Fred",42)

用readLine函數從控制檯讀取一行輸入:

val name = readLine("Your name: ")

2.5 循環

Scala擁有與Java和C++相同的while和do循環,如:

while(n > 0){
    r = r * n
    n -= 1
}

for循環使用for(i <- 表達式)這樣的語法結構,讓變量i遍歷表達式的全部值,如:

for(i <- 1 to n)
    r = r * i

遍歷字符串或數組時,一般須要使用0到n-1的區間,until方法返回一個不包含上限的區間:

val s = "hello"
var sum = 0
for(i <- 0 until s.length)
    sum += s(i)

或:

var sum = 0
for(ch <- 0 "hello") sum += ch

Scala沒有提供break或continue語句來退出循環,咱們能夠:
1.使用Boolean型的控制變量。
2.嵌套函數,函數中return。
3.使用Breaks對象中的break方法。

2.6 高級for循環

多個生成器:

for(i <- 1 to 3; j <- 1 to 3) print((10*i+j)+" ")
//打印11 12 13 21 22 23 31 32 33

生成器可帶守衛(注意:if前無分號):

for(i <- 1 to 3; j <- 1 to 3 if i!=j) print((10*i+j)+" ")
//打印12 13 21 23 31 32

for推導式(yield),循環會構造出一個集合,集合與第一個生成器的類型兼容:

for(i <- 1 to 10) yield i%3
//生成Vector(1,2,0,1,2,0,1,2,0,1)
for(c <- "Hello"; i <- 0 to 1) yield (c+i).toChar
//生成"HIeflmlmop"
for(i <- 0 to 1; c <- "Hel") yield (c+i).toChar
//生成Vector('H','e','l','I','f','m')

2.7 函數

定義函數須要名稱,參數,函數體:

def abs(x:Double) = if(x >= 0) x else -x

函數可使用代碼塊,塊中最後一個表達式的值是函數的返回值:

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)

2.8 過程

過程就是不返回值的函數,返回類型爲Unit。定義時能夠略去'=',如:

def box(s:String){
    var border = "-" * s.length + "--\n"
    println(border + "|" + s +"|\n" + border)
}

也能夠顯示聲明:

def box(s:String): Unit = {
    var border = "-" * s.length + "--\n"
    println(border + "|" + s +"|\n" + border)
}

3.數組

3.1 定長數組Array

val nums = new Array[Int](10)
//10個整數的數組,全部元素初始化爲0
val a = new Array[String](10)
//10個元素的字符串數組,全部元素初始化爲null
val s = Array("Hello","World")
//已提供初始值時不須要new
s(0) = "Goodbye"
//使用()來訪問元素

在JVM中,Scala的Array以Java數組實現,好比Array(2,3,5,7,11)在JVM中就是一個Int[]

3.2 變長數組ArrayBuffer

對於長度按需變化的數組,Java有ArrayList,C++有vector,Scala中的等效數據結構爲ArrayBuffer。

val b = ArrayBuffer[Int]()
//或val b = new ArrayBuffer[Int]
b += 1
//用+=在尾端添加元素
b += (1,2,3,5)
//添加多個元素
b ++= Array(8,13,21)
//用++=追加任何集合
b.trimEnd(5)
//移除最後5個元素

有時須要構建一個Array,但不知道最終要裝多少元素,能夠先構建一個數組緩衝ArrayBuffer,而後轉化爲Array:

b.toArray

同時,你可使用insertremove來插入或移除元素。

3.3 遍歷數組

使用for循環:

for (i <- 0 until a.length)
    println(i + ": " + a(i))

until是RichInt類的方法,0 until 10其實是0.until(10),若是想讓區間是每兩個元素一跳,能夠這樣寫0 until (a.length, 2),若是從數組尾端開始,能夠這樣寫(0 until a.length).reverse

若是在循環體中不須要用到數組下標,咱們能夠直接訪問數組元素:

for(elem <- a)
    println(elem)

3.4 數組轉換

在Scala,從一個數組或變長數組出發,以某種方式對它進行轉換是很簡單的,這些轉換動做不會修改原始數組,而是產生一個全新的數組。
好比使用for yield推倒式:

val a = Array(2,3,5,7,11)
val result = for (elem <- a) yield 2 * elem
//result是Array(4,6,10,14,22)

當你遍歷一個集合,只想處理那些知足特定條件的元素時,你能夠加入守衛,好比這裏對每一個偶數元素翻倍,丟到奇數元素:

for (elem <- a if elem % 2 == 0) yield 2 * elem

另外一種作法:

a.filter(_ % 2 == 0).map(2 * _)

3.5 數組經常使用算法

求最小和最大minmax
求和(數值類型):

Array(1,7,2,9).sum
//19

排序sorted

val b = ArrayBuffer(1,7,2,9)
val bSorted = b.sorted //ArrayBuffer(1,2,7,9)

排序(提供比較函數)sortWwith

val bDescending = b.sortWith(_ > _) //ArrayBuffer(9,7,2,1)

顯示mkString

b.mkString(" and ")
//"1 and 7 and 2 and 9"

顯示toString

b.toString
//"ArrayBuffer(1,7,2,9)"

3.6 多維數組

多維數組是經過數組的數組來實現的,舉例來講,Double的二維數組類型爲Array[Array[Double]],構造時能夠用ofDim方法:

val matrix = Array.ofDim[Double](3,4) //3*4

訪問元素時使用兩對圓括號:

matrix(row)(column) = 42

參考書籍:

相關文章
相關標籤/搜索