成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Scala如何改變了我的編程風格:從命令式到函數式

原創
開發 后端
有時候學習一門新的編程語言,也會影響到你在其他語言中的編碼方式。在這篇隨筆中,Bill Venners與我們一起分享了學習Scala是如何影響到他的編程風格的。

51CTO編輯推薦:Scala編程語言專題

【51CTO快譯】編者前言:這篇文章最初寫于2008年底,作者Bill Venners一方面是美國著名開發網站Artima的總編,另一方面也是一位十分關注Scala語言的Java程序員。在這幾個月間的Scala創始人Martin Odersky訪談系列中,與Martin對話的正是Bill Venners。這篇文章雖然已經完成了半年有余,但對于還不很熟悉Scala語言的Java程序員而言,仍然是一篇非常實用的Scala語言簡介。以下是譯文:

每次我學習一門新的語言,我都會學到某些編程方面的東西。比如說,當我以一個C++程序員的身份學習Java的時候,Java的接口構造教會我來自純粹的抽象基類的多重繼承的價值。盡管在C++里面這種編程風格是有可能的,但在我使用C++的日子里,我卻沒有考慮用這種方式進行多重繼承,而我在C++設計中也不怎么使用抽象基類。然而,一旦我開始進行Java編程,我就開始一直使用這種風格了。學習Java—尤其是它的接口構造改變了我OO設計的方法。

51CTO編輯推薦:充分利用面向對象語言的接口特性 | 面向對象的思維過程

我學習Scala編程的時候也發生了類似的情況。在過去的兩年里,我有相當多的時間是用Scala工作的,ScalaJava平臺上的一種新的靜態類型語言,它融合了面向對象編程和函數型程序設計的概念。Scala能讓我寫出幾乎跟RubyPython一樣簡潔的代碼。在Scala我可以跟在Java里面一樣方便地調用Java庫,包括我已有的Java庫。考慮到Scala是靜態類型的,我可以享受到諸多靜態類型的好處,諸如將文檔作為類型,IDE代碼自動完成,動態代碼重構(deterministic refactoring)以及執行速度等(Scala程序的執行速度跟Java的一樣快)。但Scala還讓我以簡潔和類型安全的方式獲得某些通常是動態語言的好處,例如在已有類上增加新方法的能力,或者將類型傳遞給沒有共同繼承關系的方法。

Scala是怎樣改變了我對編程的看法的呢?一句話:我學會了欣賞函數化的風格。函數化的編程風格強調不可變對象、變量可被初始化但不能重新賦值(Java中的最終變量)、數據結構轉換,以及方法和控制的構造,最終產生一個沒有副作用的結果。這個領域的另一端是命令式的風格,以可變對象、變量可被重新賦值(Java里的正常變量)、在數據結構中索引、以及帶副作用的方法和控制構造為特征。

盡管Scala經常被吹捧為函數型編程語言,當它并不僅僅是函數型的。Scala同時支持函數式和命令式兩種風格。如果你自己選擇要這么做的話,你可以以Java的編程方式進行Scala編程,那種風格主要是命令式的。這樣有助于Scala的學習曲線變緩,但隨著對Scala越來越熟悉,你就會發現自己會更喜歡函數式的。我就是這樣。為什么?因為我發現函數型風格往往要比命令式風格的代碼更簡潔,且更不易出錯。函數式風格的代碼通常層次更高,這使得它編寫起來更快,閱讀也更為容易。舉個例子,看看下面這段確定一個字符串是否包含大寫字符的Java代碼。

boolean nameHasUpperCase = false; // 這是Java

for (int i = 0; i < name.length(); ++i) {

    if (Character.isUpperCase(name.charAt(i))) {

        nameHasUpperCase = true;

        break;

    } 

}

這里的命令式風格是很明顯的,因為nameHasUpperCase變量被重新賦值會給loop循環帶來副作用,loop是通過字符串中的字母索引進行迭代的。在Java你還可以以更為簡潔的方式得到相同的結果,像下面這樣:

boolean nameHasUpperCase = !name.toLowerCase().equals(name);

這一行Java代碼展現出一種更為函數化的風格,因為它轉換不可變數據:name這個字符串被轉換為另外一個全部字母都是小寫的字符串,然后值被轉換為布爾結果。此外,nameHasUpperCase這個變量被初始化了,但僅限于這一小塊代碼里,而沒有被重新賦值。如果該變量為最終值的話,它的函數化就會更為清晰。

Scala里面,你可以寫出跟以上兩個例子類似的代碼,不過更為理想的編寫方式是像下面這樣的:

val nameHasUpperCase = name.exists(_.isUpperCase)

nameHasUpperCase變量被定義為 val,即可被初始化但不能被重新賦值的變量(類似于Java里面的最終變量)。甚至于盡管本例中并無顯式的類型標注,Scala的類型推斷機制也會給nameHasUpperCase賦予Boolean類型。exists 方法在對象集合中迭代,并依次將每個元素傳遞給函數對象。在這里, name字符串被視為字符集合,因此exists會把字符串的每一個字符都傳遞給該函數。_.isUpperCase的語法是Scala里的一種函數顯式聲明(function literal),是一種編寫少量代碼就可以到處傳遞和調用的速寫方式。下劃線代表該函數的唯一參數。因此你可以把下劃線視為每次該函數被調用時待填的空白。如果exists 方法發現該函數因被傳遞的字符中的其中一個而返回true—比如說,其中一個字符是大寫的而返回true。否則就返回false

盡管最后的這個單行代碼對于某些不熟悉Scala的人來說像是天書,只要你了解了Scala,你就能一眼看出代碼的目的。相反,其他的兩個版本卻要費上一點功夫去研究一下。另外需要注意的一點不同是命令式例子中潛在的偏移錯誤,因為你必須顯式地指出迭代的上標。在函數化的版本里這種錯誤不會產生,在這種方式下,函數化版本相對而言不易出錯。

最后,我想指出的是我轉向Scala的時候并沒有“徹底函數化”。盡管我已經發現通常大部分情況下函數化風格的代碼來得更為簡潔、明晰,更不易出錯,我還發現有時候命令式風格也可帶來更為清晰和簡潔的代碼。在那種情況下,我就會使用命令式的。Scala允許我方便地應用函數式和命令式的風格,結合使用此二者,我就能找到寫出清晰代碼的最佳方式。

#p#

函數式編程和命令式編程簡介

什么是函數式編程?(參考資料:《征服RIA:基于JavaScript的Web客戶端開發》第8章JavaScript函數對象

在數學領域,函數是一種關系,這種關系使一個集合里的每一個元素對應到另一個集合里的唯一元素。函數是將唯一的輸出值賦予每一輸入的"法則"。這一"法則"可以用函數表達式、數學關系,或者一個將輸入值與輸出值對應列出的簡單表格來表示。函數最重要的性質是其決定性,即同一輸入總是對應同一輸出(注意,反之未必成立)。從這種視角,可以將函數看做"機器"或者"黑盒",它將有效的輸入值變換為唯一的輸出值。通常將輸入值稱做函數的參數,將輸出值稱做函數的值。

《Why Functional Programming Matters》的作者John Hughes 說明了模塊化是成功編程的關鍵,而函數編程可以極大地改進模塊化。在函數編程中,編程人員有一個天然框架用來開發更精練的、更小的、更簡單的和更一般化的模塊,然后將它們組合在一起。函數式編程的基本特點是:

豐富的數據類型;

函數是運算元;

在函數內保存數據;

函數內的運算對函數外無副作用。

函數式編程只描述在程序輸入上執行的操作,不必使用臨時變量保存中間結果。重點是捕捉"是什么以及為什么",而不是"如何做"。與將重點放在執行連續命令上的過程性編程相比,函數式編程的重點是函數的定義而不是狀態機(State Machine)的實現。是一種強調表達式的計算而非命令的執行的一種編程風格。表達式是用函數結合基本值構成的,它類似于用參數調用函數(函數式的優美的說明可見《Functional Programming For The Rest of Us》)。

什么是命令式編程?(參考資料:維基百科)

命令式編程,是種描述電腦所需作出的行為的編程典范。幾乎所有電腦的硬體工作都是命令式的;幾乎所有電腦的硬體都是設計來執行機器碼,使用命令式的風格來寫的。較高階的命令式編程語言使用變數和更復雜的語句,但仍依從相同的典范。食譜和行動清單,雖非電腦程式,但與命令式編程有相似的風格:每步都是指令,有形的世界控制情況。因為命令式編程的基礎觀念,不但概念上比較熟悉,而且較容易具體表現于硬體,所以大部分的編程語言都是命令式的。

原文:How Scala Changed My Programming Style  作者:Bill Venners

【相關閱讀】

  1. Scala的類型系統 比Java更靈活
  2. Java程序員,你為什么要關注Scala
  3. Scala創始人:創造比Java更好的語言
  4. Java以外的選擇 Scala編程語言簡介
  5. Java之外,選擇Scala還是Groovy?
責任編輯:yangsai 來源: 51CTO.com
相關推薦

2019-09-09 11:40:18

編程函數開發

2009-07-09 00:25:00

Scala函數式

2009-07-21 17:16:34

Scala函數式指令式

2009-06-22 14:59:51

AOP實現原理聲明式編程命令式編程

2010-03-11 10:34:22

Scala

2017-03-22 11:22:04

JavaScript函數式編程

2010-01-28 14:51:24

Scala后函數式

2009-07-08 16:10:24

Scala簡介面向對象函數式

2009-09-27 15:23:00

Scala講座函數式編程Scala

2011-08-24 09:13:40

編程

2013-06-27 09:31:37

聲明式編程命令式編程編程

2009-12-11 10:44:00

Scala講座函數 scala

2020-09-23 07:50:45

Java函數式編程

2020-09-22 11:00:11

Java技術開發

2013-09-09 09:41:34

2012-09-21 09:21:44

函數式編程函數式語言編程

2010-07-09 14:12:00

ScalaF#C#

2010-07-07 13:11:20

ScalaF#C#

2023-07-10 09:39:02

lambdaPython語言

2023-12-14 15:31:43

函數式編程python編程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 武道仙尊动漫在线观看 | 超碰成人av | 精品美女 | 精品国产18久久久久久二百 | 中文字幕一区在线观看视频 | 欧美日韩国产一区二区三区 | 91文字幕巨乱亚洲香蕉 | 欧美日韩国产一区二区三区 | 午夜羞羞| 亚洲综合色婷婷 | 黑人精品欧美一区二区蜜桃 | 国产一级免费视频 | 成人性生交大免费 | 国产在线一区二区三区 | 日韩a在线| 欧美成人二区 | 精品欧美一区二区在线观看视频 | 国产欧美久久一区二区三区 | 天天操夜夜看 | 成人中文字幕在线观看 | 日本一区二区三区在线观看 | 91视频在线 | 久久久久久精 | 亚洲一区国产 | 在线免费黄色小视频 | 日韩综合一区 | 国产91久久久久久久免费 | 91精品国产综合久久久久久 | 久久久久久免费看 | 日韩一二三区视频 | 欧美中文在线 | 欧美男人天堂 | 在线成人一区 | 亚洲成人精选 | 99热在线观看精品 | 国产欧美一区二区精品忘忧草 | 黄色网址在线免费观看 | 国产精品爱久久久久久久 | 久久亚洲综合 | 亚洲欧美一区二区三区1000 | 欧美亚洲国产日韩 |