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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...