日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scala 指南

發(fā)布時間:2025/3/21 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scala 指南 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Scala 指南

開始精彩的Scala旅程

?下一頁

Hello World

Scala 是一門 函數(shù)式面向?qū)ο?/strong>語言。他運(yùn)行在Java虛擬機(jī)上.

本指南是用來介紹Scala強(qiáng)大的功能。同時你可以親身實(shí)踐他們。

點(diǎn)擊左邊的Run按鈕試試。左邊的運(yùn)行框可以在遠(yuǎn)程編譯和運(yùn)行任何Scala代碼。運(yùn)行的結(jié)果將展示在下面對文本框中。你也可以試著編輯這些代碼,重新運(yùn)行。(初次運(yùn)行可能會有些慢,不過第二次就很快了)

使用方向鍵或者空格來翻頁

?下一頁

基礎(chǔ)開始

目錄(基礎(chǔ))

  • 表達(dá)式和值
  • 函數(shù)是一等公民
  • 借貸模式
  • 按名稱傳遞參數(shù)
  • 定義類
  • 鴨子類型
  • 柯里化
  • 范型
  • Traits
?概覽 ?下一頁

表達(dá)式和值

在Scala中,幾乎所有的語言元素都是表達(dá)式。

println("hello wolrd")

是一個表達(dá)式,

"hello"+" world"

也是一個表達(dá)式。

可以通過val定義一個常量,亦可以通過var定義一個變量。推薦多使用常量。

?目錄 ?下一頁

函數(shù)是一等公民

可以使用def來定義一個函數(shù)。函數(shù)體是一個表達(dá)式。

使用Block表達(dá)式的時候,默認(rèn)最后一行的返回是返回值,無需顯式指定。

函數(shù)還可以像值一樣,賦值給var或val。因此函數(shù)也可以作為參數(shù)傳給另一個函數(shù)。

?上一頁 ?目錄 ?下一頁

借貸模式

由于函數(shù)可以像值一樣作為參數(shù)傳遞,所以可以方便的實(shí)現(xiàn)借貸模式。

這個例子是從/proc/self/stat文件中讀取當(dāng)前進(jìn)程的pid。

withScanner封裝了try-finally塊,所以調(diào)用者不用再close

注:當(dāng)表達(dá)式?jīng)]有返回值時,默認(rèn)返回Unit。

?上一頁 ?目錄 ?下一頁

按名稱傳遞參數(shù)

這個例子演示了按名稱傳遞參數(shù),由于有除以0,所以運(yùn)行該程序會產(chǎn)生異常。

試著將

def log(msg: String)

修改為

def log(msg: => String)

由按值傳遞修改為按名稱傳遞后將不會產(chǎn)生異常。

因?yàn)閘og函數(shù)的參數(shù)是按名稱傳遞,參數(shù)會等到實(shí)際使用的時候才會計(jì)算,所以被跳過。

按名稱傳遞參數(shù)可以減少不必要的計(jì)算和異常。

?上一頁 ?目錄 ?下一頁

定義類

可以用class關(guān)鍵字來定義類。并通過new來創(chuàng)建類。

在定義類時可以定義字段,如firstName,lastName。這樣做還可以自動生成構(gòu)造函數(shù)。

可以在類中通過def定義函數(shù)var和val定義字段

函數(shù)名是任何字符如+,-,*,/。

試著將

obama.age_=(51)

簡化為

obama.age = 51

這樣的簡化更像調(diào)用一個變量。

?上一頁 ?目錄 ?下一頁

鴨子類型

走起來像鴨子,叫起來像鴨子,就是鴨子。

這個例子中使用

{ def close(): Unit }

作為參數(shù)類型。因此任何含有close()的函數(shù)的類都可以作為參數(shù)。

不必使用繼承這種不夠靈活的特性。

?上一頁 ?目錄 ?下一頁

柯里化

這個例子和上面的功能相同。不同的是使用了柯里化(Currying)技術(shù)。

def add(x:Int, y:Int) = x + y

是普通的函數(shù)

def add(x:Int) = (y:Int) => x + y

是柯里化后的函數(shù),相當(dāng)于返回一個匿名函數(shù)表達(dá)式。

def add(x:Int)(y:Int) = x + y

是簡化寫法

柯里化可以讓我們構(gòu)造出更像原生語言提供的功能的代碼

試著將例子中的withclose(...)(...)換成withclose(...){...}

?上一頁 ?目錄 ?下一頁

范型

之前的例子可以使用泛型變得更簡潔更靈活。

試著將

"123456"

修改為

123456

雖然msg由String類型變?yōu)镮nt類型,但是由于使用了泛型,代碼依舊可以正常運(yùn)行。

?上一頁 ?目錄 ?下一頁

Traits

Traits就像是有函數(shù)體的Interface。使用with關(guān)鍵字來混入。

這個例子是給java.util.ArrayList添加了foreach的功能。

試著再在with ForEachAble[Int]后面加上

with JsonAble

給list添加toJson的能力

?上一頁 ?目錄?下一頁

函數(shù)式開始

目錄(函數(shù)式)

  • 模式匹配
  • Case Class
  • 函數(shù)式的威力
  • 函數(shù)式真正的威力
  • Word Count
  • 尾遞歸
  • 更強(qiáng)大的For循環(huán)
  • Option
  • Lazy初始化
?概覽 ?下一頁

模式匹配

模式匹配是類似switch-case特性,但更加靈活;也類似if-else,但更加簡約。

這個例子展示的使用用模式匹配實(shí)現(xiàn)斐波那契。 使用case來匹配參數(shù),如果case _,則可以匹配任何參數(shù)。

試著將

case n: Int

修改為

case n: Int if (n > 1)

case后添加if語句判斷,這樣修改當(dāng)輸入負(fù)數(shù)時,就不會無限循環(huán)。

模式匹配也可以匹配類型,在case _ 前加上

case n: String => fibonacci(n.toInt)

這樣就可以匹配String類型

?目錄 ?下一頁

Case Class

case class 顧名思義就是為case語句專門設(shè)計(jì)的類, 在普通類的基礎(chǔ)上添加了和類名一直的工廠方法, 還添加了hashcode,equals和toString等方法。

由于使用了require(n >= 0)來檢驗(yàn)參數(shù),如果使用負(fù)數(shù)計(jì)算,將會拋出異常。

?上一頁 ?目錄 ?下一頁

函數(shù)式的威力

這個例子是用指令式編程判斷一個List中是否含有奇數(shù)。

試著將

containsOdd(list)

替換為

list.exists((x: Int) => x % 2 ==1)

通過將函數(shù)作為參數(shù),可以使程序更簡潔。還可以再簡化為

list.exists(_ % 2 == 1)

可以用_替代參數(shù)

相比于Ruby等動態(tài)語言,這威力來自于科學(xué)而不是魔法

?上一頁 ?目錄 ?下一頁

函數(shù)式真正的威力

函數(shù)式除了能簡化代碼外,更重要的是他關(guān)注的是InputOutput,函數(shù)本身沒有副作用。

就是Unix pipeline一樣,簡單的命令組合在一起威力無窮。

如果你喜歡Unix pipeline的方式,你一定也會喜歡函數(shù)式編程。

這個例子是用函數(shù)式的代碼模擬

cat file | grep 'warn' | grep '2013' | wc

List的filter方法接受一個過濾函數(shù),返回一個新的List,作為下一個方法的輸入。

?上一頁 ?目錄 ?下一頁

Word Count

Word Count是一個MapReduce的一個經(jīng)典示例。在函數(shù)式編程中,Word Count最直觀的實(shí)現(xiàn)方法也是MapReduce。

這個例子介紹了List的兩個重要的高階方法mapreduceLeft

map接受一個轉(zhuǎn)換函數(shù),返回轉(zhuǎn)換結(jié)果。

reduceLeft接受一個合并函數(shù),依次遍歷合并。

使用高階方法可以代替大部分需要循環(huán)的操作,使代碼更清晰

?上一頁 ?目錄 ?下一頁

尾遞歸

尾遞歸是遞歸的一種,特點(diǎn)在于會在函數(shù)的最末調(diào)用自身。尾遞歸是函數(shù)式編程的常見寫法。

這個例子是foldLeft的尾遞歸實(shí)現(xiàn)。foldLeft和reduceLeft相比更常用,多一個初始參數(shù)。

當(dāng)用List做match case時。可以使用 :: 來解構(gòu)。返回第一個元素head和剩余元素tail。

注:尾遞歸會在編譯期優(yōu)化,因此不用擔(dān)心遞歸造成的棧溢出問題。

?上一頁 ?目錄 ?下一頁

更強(qiáng)大的For循環(huán)

循環(huán)語句是指令式編程的常見語句,Scala對其加以改進(jìn),成為適應(yīng)函數(shù)式風(fēng)格的利器。

For循環(huán)也是有返回值的,返回的是一個List。在每一輪迭代中加入yield,yield后的值可以加入到List中。

這個例子是使用for循環(huán)代替map函數(shù)。

?上一頁 ?目錄 ?下一頁

Option

Scala提供了Option機(jī)制來解決,代碼中不斷檢查null的問題。

這個例子包裝了getProperty方法,使其返回一個Option。 這樣就可以不再漫無目的地null檢查。只要Option類型的值即可。

使用pattern match來檢查是常見做法。也可以使用getOrElse來提供當(dāng)為None時的默認(rèn)值。

給力的是Option還可以看作是最大長度為1的List,List的強(qiáng)大功能都可以使用。

再見 NullException

?上一頁 ?目錄 ?下一頁

Lazy初始化

Lazy可以延遲初始化字段。加上lazy的字段會在第一次訪問的時候初始化,而不是類初始化的時候初始化。

這個例子是從github獲得Scala的版本號,由于訪問網(wǎng)絡(luò)需要較多時間。可以使用lazy來延遲獲取。 防止可能的浪費(fèi)。

Lazy非常適合于初始化非常耗時的場景

?上一頁 ?目錄?下一頁

并發(fā)開始

目錄(并發(fā))

  • 使用Actor
  • Actor更簡化的用法
  • Actor原理
  • 同步返回
  • 異步返回
  • 并行集合
  • 并行wordcount
  • 遠(yuǎn)程Actor
?概覽 ?下一頁

使用Actor

Actor是Scala的并發(fā)模型。在2.10之后的版本中,使用Akka作為其推薦Actor實(shí)現(xiàn)。

Actor是類似線程的實(shí)體,有一個郵箱。 Actor可以通過system.actorOf來創(chuàng)建,receive獲取郵箱消息,向郵箱發(fā)送消息。

這個例子是一個EchoServer,接受信息并打印。

?目錄 ?下一頁

Actor更簡化的用法

可以通過更簡化的辦法聲明Actor。

通過

akka.actor.ActorDSL

中的actor函數(shù)。這個函數(shù)可以接受一個Actor的構(gòu)造器Act,啟動并返回Actor。

?上一頁 ?目錄 ?下一頁

Actor原理

Actor比線程輕量。在Scala中可以創(chuàng)建數(shù)以百萬級的Actor。奧秘在于Actor直接可以復(fù)用線程

Actor和線程是不同的抽象,他們的對應(yīng)關(guān)系是由Dispatcher決定的。

這個例子創(chuàng)建4個Actor,每次調(diào)用的時候打印自身線程名稱。

可以發(fā)現(xiàn)Actor和線程之間沒有一對一的對應(yīng)關(guān)系。一個Actor可以使用多個線程,一個線程也會被多個Actor復(fù)用。

?上一頁 ?目錄 ?下一頁

同步返回

Actor非常適合于較耗時的操作。比如獲取網(wǎng)絡(luò)資源。

這個例子通過調(diào)用ask函數(shù)來獲取一個Future。

在Actor內(nèi)部通過 sender ! 傳遞結(jié)果。

Future像Option一樣有很多高階方法,可以使用foreach查看結(jié)果。

?上一頁 ?目錄 ?下一頁

異步返回

異步操作可以最大發(fā)揮效能。Scala的Futrue很強(qiáng)大,可以異步返回。

可以實(shí)現(xiàn)Futrue的onComplete方法。當(dāng)Futrue結(jié)束的時候就會回調(diào)。

在調(diào)用ask的時候,可以設(shè)定超時。

?上一頁 ?目錄 ?下一頁

并行集合

這個例子是訪問若干URL,并記錄時間。如果能并行訪問,就可以大幅提高性能。

嘗試將

urls.map

修改為

urls.par.map

這樣每個map中的函數(shù)都可以并發(fā)執(zhí)行。

當(dāng)函數(shù)式和并發(fā)結(jié)合,就會這樣讓人興奮。

?上一頁 ?目錄 ?下一頁

并行wordcount

這個例子是訪問若干URL,并記錄時間。

并行集合支持大部分集合的功能。

在前面有一個wordcount例子,也可以用并行集合加以實(shí)現(xiàn)。

不增加程序復(fù)雜性,卻能大幅提高利用多核的能力。

?上一頁 ?目錄 ?下一頁

遠(yuǎn)程Actor

Actor是并發(fā)模型,也使用于分布式。

這個例子創(chuàng)建一個Echo服務(wù)器,通過actorOf來注冊自己。

然后再創(chuàng)建一個client,通過akka url來尋址。

除了是通過url創(chuàng)建的,其他使用的方法和普通Actor一樣。

?上一頁 ?目錄?下一頁

實(shí)踐開始

目錄(實(shí)踐)

  • 使用Java
  • 相等性
  • 抽取器
  • 記憶模式
  • 隱式轉(zhuǎn)換
  • DSL
  • 測試
  • Simple Build Tool
?概覽 ?下一頁

使用Java

Scala和Java可以非常方便的互操作,前面已經(jīng)有大量Scala直接使用Java的例子。

同樣Java也可以使用Scala。這個例子演示使用@BeanProperty注解來生成Java Style的Bean。

嘗試將

var name: String

修改為

@BeanProperty var name: String

這樣就給bean添加了getter/setter。 Apache BeanUtils就可以正常工作。

?目錄 ?下一頁

相等性

在Scala中==等效于equals,這一點(diǎn)和Java不同。更自然一些。

寫一個完全正確的equal函數(shù)并不容易,這個例子也有子類會不對稱的Bug。

嘗試將class修改為case class,并刪除equals函數(shù)。

case類會自動生成正確的equals函數(shù)。

?上一頁 ?目錄 ?下一頁

抽取器

抽取器可以幫助模式匹配進(jìn)行解構(gòu)。

這個例子是構(gòu)建一個Email抽取器,只要實(shí)現(xiàn)unapply函數(shù)就可以了。

Scala的正則表達(dá)式會自帶抽取器,可以抽取出一個List。List里的元素是匹配()里的表達(dá)式。

抽取器很有用,短短的例子里就有兩處使用抽取器:

case user :: domain :: Nil

解構(gòu)List

case Email(user, domain)

解構(gòu)Email。

?上一頁 ?目錄 ?下一頁

記憶模式

記憶模式可以解決手動編寫存取cache代碼的麻煩。

這個例子中,memo可以將一個不含cache函數(shù),包裝成一個含有cache功能的。

還是斐波那契的例子,通過cache可以使性能提高。

嘗試將

fibonacci_(n - 1) + fibonacci_(n - 2)

修改為

memo(fibonacci_)(n - 1) + memo(fibonacci_)(n - 2)

可以提高更多性能。

?上一頁 ?目錄 ?下一頁

隱式轉(zhuǎn)換

implicit可以定義一個轉(zhuǎn)換函數(shù),可以在使用相應(yīng)類型的時候自動轉(zhuǎn)換。

這個例子可以將String自動轉(zhuǎn)換為Date類型。隱式轉(zhuǎn)換時實(shí)現(xiàn)DSL的重要工具。

?上一頁 ?目錄 ?下一頁

DSL

DSL是Scala最強(qiáng)大武器,可以使一些描述性代碼變得極為簡單。

這個例子是使用DSL生成JSON。Scala很多看似是語言級的特性也是用DSL做到的。

自己編寫DSL有點(diǎn)復(fù)雜,但使用起來非常方便。

?上一頁 ?目錄 ?下一頁

測試

Scala可以使用Spec2,ScalaTest來測試, DSL可以使測試更方便。

這個例子是測試一個階乘函數(shù)。使用should/in來建立測試用例。

測試是默認(rèn)并發(fā)執(zhí)行的。

?上一頁 ?目錄 ?下一頁

Simple Build Tool

SBT是Scala的最佳編譯工具,在他的幫助下,

你甚至不需要安裝除JRE外的任何東西,來開發(fā)Scala。

例如你想在自己的機(jī)器上執(zhí)行這個Scala-Tour,可以執(zhí)行左邊的命令

?上一頁 ?目錄?下一頁

關(guān)于

這個指南源自于作者對Scala的熱愛和對傳播Scala的愿望

其他資料:

  • Scala School!: Twitter的Scala教學(xué)
  • A Tour of Scala:官方Scala Tour
  • Scala By Example:更多的Scala例程
  • Scala Cheatsheet:一眼望穿Scala基本語法
  • Functional Programming Principles in Scala:Coursera 的Scala課程

from: http://zh.scala-tour.com/#/basics-contents

總結(jié)

以上是生活随笔為你收集整理的Scala 指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。