Scala 基礎入門【翻譯】

来源:http://www.cnblogs.com/liuning8023/archive/2016/02/12/5186947.html
-Advertisement-
Play Games

原文地址 本文只是帶你進入 Scala 的世界,包括安裝、不可變變數 val、可變變數 var、定義類、集合(包括列表(list)、集(set)、映射(map))以及集合遍歷和集合庫(能達到並行/併發效果)。 題外話,如果 Java 爭氣的話,還就真不會出現像 Scala 這些語言。對於函數編程風格...


原文地址

本文只是帶你進入 Scala 的世界,包括安裝、不可變變數 val、可變變數 var、定義類、集合(包括列表(list)、集(set)、映射(map))以及集合遍歷和集合庫(能達到並行/併發效果)。

題外話,如果 Java 爭氣的話,還就真不會出現像 Scala 這些語言。對於函數編程風格的支持,尤其是對於 Lambda 表達式的支持,能夠有助於減少必須要編寫的邏輯無關樣板代碼,也許讓它可以更簡單的關註要面對的任務本身。而 Java 對 Lamdba 表達式的支持到 JavaSE8 才實現(你可以查一下 Java SE8 什麼發佈的,而其他語言何時支持匿名函數、Lambda 表達式、函數式編程、並行編程……)。

Scala,一門強類型定義的靜態類型語言,結合了面向對象編程與函數編程思想,語法簡潔,完全相容Java,運行在 JVM 上。JVM 上的其他語言:Groovy、JRuby、Clojure。那麼 Scala 有什麼不同?能同時提供函數式風格和良好併發支持的強類型語言,只有 Scala。JRuby 和 Groovy 都是動態語言(Scala 是靜態類型語言),它們不是函數式的,也無法提供比 Java 更好的併發解決方案。另一方面,Clojure 是一種混合型的函數式語言,它天生就是動態的,因此不是靜態類型。而且它的語法類似 Lisp,除非你很熟悉,否則這可不是一種易於掌握的語言(Lisp 是號稱高智商的人才能使用的語言,如果你看過《黑客與畫家》,應該記得作者的一句話,大意是,如果競爭對手採用 Lisp 開發 Web,那就應該小心了,言下之意是,Lisp 跟其他語言相比,生產效率太高了,很容易實現一個想法)。

文中代碼本人在 Scala 2.11 上編譯並運行通過。

作為第一步,先安裝好最新的 Scala 發佈包 Typesafe stack,打開命令行視窗,鍵入“scala”:這將啟動 REPL(讀入-運算 輸出 迴圈)互動式編碼環境。然後就可以寫下你的第一行 Scala 代碼:

scala> val columbus: Int = 1492
 
columbus: Int = 1492
 
scala>

聲明瞭一個類型為 Int 變數,初始值為 1492,就像在Java里 Int columbus = 1492; 一樣。

Scala 把類型放在變數之後(反向的聲明方式),還使用“val”顯性地把變數聲明為不可變。如果想修改這個變數:

scala> columbus=1500
 
<console>:8: error: reassignment to val
 
       columbus=1500
 
               ^
 
scala>

錯誤消息精確地指出了錯誤位於行的位置。

再嘗試聲明這個變數,但這次用“var”,讓其可變更。這樣編譯器能推斷出 1492 是一個整數,也就不需要指定類型了:

scala> var columbus = 1492
 
columbus: Int = 1492
 
scala> columbus = 1500
 
columbus: Int = 1500
 
scala>

接下來,我們來定義一個類,名為 Employee,有三個不可變更的欄位:name、age 和 company,擁有各自的預設值。

scala> case class Employee(name:String="guest",
 
     | age:Int=30,
 
     | company:String="DevCode")
 
defined class Employee
 
scala>

關鍵字“case”相當於 Java 里的 switch 語句,只不過更為靈活。它說明該類具有模式匹配的額外機制,以及其他一些特性,包括用來創建實例的工廠方法(不需要使用“new”關鍵字來構造),同樣也不需要創建預設的 getter 方法。與 Java 中不同的是,變數預設下的訪問控制是 public(而不是protected),而Scala為公開變數創建一個 getter 方法,並命名為變數名。如果你願意,你也可以把欄位定義成可變且/或私有(private)的,只需要在參數之前使用“var”(例如:case class Person(private var name:String))。

我們再來用不同方式創建一些實例,看看其他的特性,像是命名參數和預設參數(從Scala2.8開始引入):

scala> val guest=Employee()
 
guest: Employee = Employee(guest,30,DevCode)
 
scala> val guestAge=guest.age
 
guestAge: Int = 30
 
scala> val anna=Employee("Anna")
 
anna: Employee = Employee(Anna,30,DevCode)
 
scala> val thomas=Employee("Thomas",41)
 
thomas: Employee = Employee(Thomas,41,DevCode)
 
scala> val luke=Employee("Luke",company="LucasArt")
 
luke: Employee = Employee(Luke,30,LucasArt)
 
scala> val yoda=luke.copy("Yoda",age=800)
 
yoda: Employee = Employee(Yoda,800,LucasArt)
 
scala>

不過,下麵的寫法是行不通的(可不是因為 Darth 不是 DevCode 的雇員!)

scala> val darth=Employee("Darth","DevCode")
 
<console>:9: error: type mismatch;
 
 found   : String("DevCode")
 
 required: Int
 
       val darth=Employee("Darth","DevCode")
 
                                  ^
 
scala>

這是由於構造函數在這個位置需要 age 作為參數,因為函數參數沒有顯性地進行命名。

現在我們再來看集合,這才是真正讓人興奮的地方。Scala 主要集合類型包括列表(list)、集(set)和映射(map)。

有了泛型(Java5 以上),Java可以遍歷一個列表,比方說整數型列表,用下麵代碼:

 
List<Integer> numbers = new arrayList<Integer>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
for(Integer n:numbers) {
    System.out.println("Number "+n);
}

運行結果:

Number 1
 
Number 2
 
Number 3

Scala 對於可變集合和不可變集合進行了系統性地區別處理,不過,鼓勵使用不可變集合,也因此在預設情況下創建不可變集合。這些集合是通過模擬的方式實現添加、更新和刪除操作,在這些操作中,不是修改集合,而是返回新的集合。

與前面的 Java 代碼等價的 Scala 代碼可能像下麵這樣:

scala> val numbers=List(1,2,3)
 
numbers: List[Int] = List(1, 2, 3)
 
scala> for(n<-numbers) println("Number "+n)
 
Number 1
 
Number 2
 
Number 3
 
scala>

這裡的“for”迴圈語法結構非常接近於 Java 的命令式編程風格。在 Scala(以及 Java 虛擬機上其他很多語言如:Groovy、JRuby 或 JPython)里還有另外一種方式來實現上面的邏輯。這種方式使用一種更加偏向函數編程的風格,引入了 Lambda 表達式(有時也稱為閉包——closure)。簡單地說,Lambda 表達式就是你可以拿來當作參數傳遞的函數。這些函數使用參數作為輸入(在我們的例子中就是“n”整型變數),返回語句作為函數體的最終語句。他們的形式如下:

functionName { input =>
    body
}
scala> numbers.foreach{n:Int=> println("Number "+n) }
 
Number 1
 
Number 2
 
Number 3
 
scala>

上面的例子中,函數體只有一條語句(println……),返回的是單位(Unit,也就是“空結果”),也就是大致相當於 Java 中的 void,不過有一點不同的是——void是不返回任何結果的。

除了列印數值列表外,我們更想做處理和變換這些元素,這時我們需要調用方法來生成結果列表,以便後面接著使用。讓我們嘗試一些例子:

scala> val reversedList=numbers.reverse
 
reversedList: List[Int] = List(3, 2, 1)
 
scala> val numbersLessThan3=numbers.filter{n=>n<3}
 
numbersLessThan3: List[Int] = List(1, 2)
 
scala> val oddNumbers=numbers.filterNot{n=>n%2==0}
 
oddNu

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天是大年初三,先跟大家拜個年,祝大家新年快樂。今天處理了一個alwaysOn問題——輔助副本因為磁碟空間不足一直顯示【未同步——可疑】,在日誌中可以看到資料庫處於掛起狀態,與主副本失去同步。原以為只需把輔助副本的磁碟做個清理,騰出一點空間,然後重啟SQL Server服務就好了(重啟讓資料庫從掛起...
  • 一、 1、現象:我們把資料庫的字元集編碼設置為utf-8,我們通過DOS界面向表的某一列插入漢字時會遇到類似 data too long for column 'name' at row 1 的錯誤。 2、錯誤原因: 3、解決的辦法: (1)set names gbk;(只對當前視窗有效) (2)找
  • 如何獲取 GemFire 8.2 安裝介質,以及在CentOS和Mac OS X的安裝過程。
  • -- 修改欄位 alter table emp MODIFY dept_id int; -- 刪除欄位 alter table emp drop COLUMN dept_id; 之前就當是 熱身了,跟著這個老師 你會覺得 真的能學到很多東西。要好好努力了! 上面兩個語句是通用性很強的語句。是 在 o
  • --1.sp_databas:列出伺服器上的所有資料庫信息,包括資料庫名稱和資料庫大小 exec sp_databases --2.sp_helpdb:報告有關指定資料庫或所有資料庫的信息 exec sp_helpdb --3.sp_renamedb:更改資料庫的名稱 exec sp_renamed
  • Nancy中Pipelines三兄弟(Before After OnError)的簡要概述以及多種用法。
  • 轉發至:http://www.ituring.com.cn/article/130823 導言 現代的應用程式面臨著諸多的挑戰,如何構建具有可伸縮性和高性能的應用成為越來越多軟體開發者思考的問題。隨著應用規模的不斷增大,業務複雜性的增長以及實時處理需求的增加,開發者不斷嘗試榨取硬體資源、優化。 在不
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...