欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
再談編程范式

編程范式

托馬斯.庫爾提出“科學(xué)的革命”的范式論后,Robert Floyd在1979年圖靈獎的頒獎演說(shuō)中使用了編程范式一詞。編程范式一般包括三個(gè)方面,以OOP為例:

  1,學(xué)科的邏輯體系——規則范式:如 類(lèi)/對象、繼承、動(dòng)態(tài)綁定、方法改寫(xiě)、對象替換等等機制。

  2,心理認知因素——心理范式:按照面向對象編程之父Alan Kay的觀(guān)點(diǎn),“計算就是模擬”。OO范式極其重視隱喻(metaphor)的價(jià)值,通過(guò)擬人化,按照自然的方式模擬自然。

  3,自然觀(guān)/世界觀(guān)——觀(guān)念范式:強調程序的組織技術(shù),視程序為松散耦合的對象/類(lèi)的組合,以繼承機制將類(lèi)組織成一個(gè)層次結構,把程序運行視為相互服務(wù)的對象之間的對話(huà)。

簡(jiǎn)單來(lái)說(shuō),編程范式是程序員看待程序應該具有的觀(guān)點(diǎn),代表了程序設計者認為程序應該如何被構建和執行的看法。

常見(jiàn)的編程范式有:命令式、過(guò)程式、說(shuō)明式、面向對象、函數式、泛型編程等。

Imperative—命令式||過(guò)程式

  * 馮諾依曼 機器語(yǔ)言、匯編語(yǔ)言 BASIC COBOL C Ada FORTRAN Fortran ,

   *腳本式 Perl Python PHP,把用其他語(yǔ)言開(kāi)發(fā)的獨立程序作為部件“粘到一起”

   *面向對象 Smalltalk C++ Java,將計算建立在獨立的對象的相互作用至上。每個(gè)對象有其自身的內部狀態(tài),以及管理自身狀態(tài)的可執行子程序

Declarative—說(shuō)明式||聲明式

   *函數式 Lisp ML Haskell ,程序被看作是一種從輸入到輸出的函數

   *數據流 ld Val,語(yǔ)言將計算看成在一些基本的功能結點(diǎn)之間流動(dòng)的信息流。結點(diǎn)由輸入單詞的到達觸發(fā),能夠并發(fā)操作

   *邏輯式 Prolog,設法根據一集邏輯規則找出滿(mǎn)足某些特定關(guān)系的值

   *基于模板的 XSLT xml html,

需要提醒的是:編程范式是編程語(yǔ)言的一種分類(lèi)方式,它并不針對某種編程語(yǔ)言。就編程語(yǔ)言而言,一種語(yǔ)言可以適用多種編程范式。

一些編程語(yǔ)言是專(zhuān)門(mén)為某種特定范式設計的,例如C語(yǔ)言是過(guò)程式編程語(yǔ)言;Smalltalk和Java是較純粹的面向對象編程語(yǔ)言;Haskell是純粹的函數式編程語(yǔ)言。另外一些編程語(yǔ)言和編程范式的關(guān)系并不一一對應,如Python,Scala,Groovy都支持面向對象和一定程度上的函數式編程。C++是多范式編程語(yǔ)言成功的典范。C++支持和C語(yǔ)言一樣的過(guò)程式編程范式,同時(shí)也支持面向對象編程范式,STL(Standard Template Library)使C++具有了泛型編程能力。支持多種范式可能是C++直到現在仍然具有強大的生命力的原因之一。

Swift是一門(mén)典型的多范式編程語(yǔ)言,即支持面向對象編程范式,也支持函數式編程范式,同時(shí)還支持泛型編程。Swift支持多種編程范式是由其創(chuàng )造目標決定的。Swift創(chuàng )造的初衷就是提供一門(mén)實(shí)用的工業(yè)語(yǔ)言。不同于Haskell這類(lèi)出自大學(xué)和研究機構的學(xué)術(shù)性質(zhì)的編程語(yǔ)言。蘋(píng)果推出Swift時(shí)就帶著(zhù)著(zhù)明確的商業(yè)目的:Mac OS和iOS系統的主要編程語(yǔ)言Objective-C已顯老態(tài),Swift將使得蘋(píng)果系統的開(kāi)發(fā)者擁有一門(mén)更現代的編程語(yǔ)言,從而促進(jìn)蘋(píng)果整個(gè)生態(tài)圈的良性發(fā)展。

命令式編程:

命令式編程的主要思想是關(guān)注計算機執行的步驟,即一步一步告訴計算機先做什么再做什么。

從本質(zhì)上講,它是“馮.諾依曼機”運行機制的抽象,它的編程思想方式源于計算機指令的順序排列。

(也就是說(shuō):過(guò)程化語(yǔ)言模擬的是計算機機器的系統構造,而并不是基于語(yǔ)言的使用者的個(gè)人能力和傾向。這一點(diǎn)我們應該都很清楚,比如我們最早曾經(jīng)使用過(guò)的單片機的匯編語(yǔ)言。)

不管你用的是 C, C++ 還是 C#, Java, Javascript, BASIC, Python, Ruby 等等,你都可以以這個(gè)方式寫(xiě)。

程序流程圖是命令式語(yǔ)言進(jìn)行程序編寫(xiě)的有效輔助手段。

命令式語(yǔ)言特別適合解決線(xiàn)性(或者說(shuō)按部就班)的算法問(wèn)題。它強調“自上而下(自頂向下)”“精益求精”的設計方式。這種方式非常類(lèi)似我們的工作和生活方式,因為我們的日?;顒?dòng)都是按部就班的順序進(jìn)行的。

命令式語(yǔ)言趨向于開(kāi)發(fā)運行較快且對系統資源利用率較高的程序。命令式語(yǔ)言非常的靈活并強大,同時(shí)有許多經(jīng)典應用范例,這使得程序員可以用它來(lái)解決多種問(wèn)題。

命令式語(yǔ)言的不足之處就是它不適合某些種類(lèi)問(wèn)題的解決,例如那些非結構化的具有復雜算法的問(wèn)題。問(wèn)題出現在,命令式語(yǔ)言必須對一個(gè)算法加以詳盡的說(shuō)明,并且其中還要包括執行這些指令或語(yǔ)句的順序。實(shí)際上,給那些非結構化的具有復雜算法的問(wèn)題給出詳盡的算法是極其困難的。

廣泛引起爭議和討論的地方是:無(wú)條件分支,或goto語(yǔ)句,它是大多數過(guò)程式編程語(yǔ)言的組成部分,反對者聲稱(chēng):goto語(yǔ)句可能被無(wú)限地濫用;它給程序設計提供了制造混 亂的機會(huì )。目前達成的共識是將它保留在大多數語(yǔ)言中,對于它所具有的危險性,應該通過(guò)程序設計的規定將其最小化。

命令式對實(shí)際事物處理一般可以拆分為以下兩種模式:

  • 流程驅動(dòng):類(lèi)似 一般就是主動(dòng)輪詢(xún) 在干活中還要分心 主動(dòng)去找活干 這樣有空余的時(shí)間也完全浪費掉了

采用警覺(jué)式者主動(dòng)去輪詢(xún) ( polling),行為取決于自身的觀(guān)察判斷,是流程驅動(dòng)的,符合常規的流程驅動(dòng)式編程 ( Flow-Driven Programming)的模式。

  • 事件驅動(dòng):類(lèi)似 比如公司有一個(gè)oa系統 你干完活的時(shí)候只需要看下oa系統有沒(méi)分配給你活 沒(méi)有可以干自己的事 不用擔心還有其他事沒(méi)干完

采用托付式者被動(dòng)等通知 (notification),行為取決于外來(lái)的突發(fā)事件,是事件驅動(dòng) 的,符合事件驅動(dòng)式編程 ( Event-Driven Programming,簡(jiǎn)稱(chēng) EDP)的模式。

事件驅動(dòng)編程

其實(shí),基于事件驅動(dòng)的程序設計在圖形用戶(hù)界面(GUI)出現很久前就已經(jīng)被應用于程序設計中,可是只有當圖形用戶(hù)界面廣泛流行時(shí),它才逐漸形演變?yōu)橐环N廣泛使用的程序設計模式。

在過(guò)程式的程序設計中,代碼本身就給出了程序執行的順序,盡管執行順序可能會(huì )受到程序輸入數據的影響。

在事件驅動(dòng)的程序設計中,程序中的許多部分可能在完全不可預料的時(shí)刻被執行。往往這些程序的執行是由用戶(hù)與正在執行的程序的互動(dòng)激發(fā)所致。

事件:就是通知某個(gè)特定的事情已經(jīng)發(fā)生(事件發(fā)生具有隨機性)。

事件與輪詢(xún):輪詢(xún)的行為是不斷地觀(guān)察和判斷,是一種無(wú)休止的行為方式。而事件是靜靜地等待事情的發(fā)生。事實(shí)上,在Windows出現之前,采用鼠標輸入字符模式的PC應用程序必須進(jìn)行串行輪詢(xún),并以這種方式來(lái)查詢(xún)和響應不同的用戶(hù)操做。

事件處理器:是對事件做出響應時(shí)所執行的一段程序代碼。事件處理器使得程序能夠對于用戶(hù)的行為做出反映。

事件驅動(dòng)常常用于用戶(hù)與程序的交互,通過(guò)圖形用戶(hù)接口(鼠標、鍵盤(pán)、觸摸板)進(jìn)行交互式的互動(dòng)。當然,也可以用于異常的處理和響應用戶(hù)自定義的事件等等。

事件的異常處理比用戶(hù)交互更復雜。

事件驅動(dòng)不僅僅局限在GUI編程應用。但是實(shí)現事件驅動(dòng)我們還需要考慮更多的實(shí)際問(wèn)題,如:事件定義、事件觸發(fā)、事件轉化、事件合并、事件排隊、事件分派、事件處理、事件連帶等等。

其實(shí),到目前為止,我們還沒(méi)有找到有關(guān)純事件驅動(dòng)編程的語(yǔ)言和類(lèi)似的開(kāi)發(fā)環(huán)境。所有關(guān)于事件驅動(dòng)的資料都是基于GUI事件的。

屬于事件驅動(dòng)的編程語(yǔ)言有:VB、C#、Java(Java Swing的GUI)等。它們所涉及的事件絕大多數都是GUI事件。

此種程化范式要求程序員用按部就班的算法看待每個(gè)問(wèn)題。很顯然,并不是每個(gè)問(wèn)題都適合這種過(guò)程化的思維方式。這也就導致了其它程序設計范式出現,包括我們現在介紹的面向對象的程序設計范式。

從編程的發(fā)展史來(lái)談面向對象的出現。當軟件還非常簡(jiǎn)單的時(shí)候,我們只需要面向過(guò)程編程:

定義函數

函數一 函數二 函數三 函數四

定義數據

數據一 數據二 數據三 數據四

最后各種函數,數據的操作。

當軟件發(fā)展起來(lái)后,我們的軟件變得越來(lái)越大,代碼量越來(lái)越多,復雜度遠超Hello World的時(shí)候,我們的編寫(xiě)就有麻煩了:函數和數據會(huì )定義得非常多,面臨兩個(gè)問(wèn)題。首先是命名沖突,英文單詞也就那么幾個(gè),可能寫(xiě)著(zhù)寫(xiě)著(zhù)取名時(shí)就沒(méi)合適的短詞用了,為了避免沖突,只能把函數名取得越來(lái)越長(cháng)。然后是代碼重復,我們可以用函數里面調用函數的方法,但是函數調函數(比如一個(gè)功能多個(gè)方法(函數),幾個(gè)功能混用方法)不便于維護。

面向對象程序

面向對象程序設計(Object-oriented programming OOP)是種通過(guò)類(lèi)、方法、對象和消息傳遞,來(lái)支持面向對象的程序設計范式。對象則指的是類(lèi)的實(shí)例。它將對象作為程序的基本單元,將程序和數據封裝其中,以提高軟件的重用性、靈活性和擴展性,對象里的程序可以訪(fǎng)問(wèn)及經(jīng)常修改對象相關(guān)連的數據。在面向對象程序編程里,程序會(huì )被設計成彼此相關(guān)的對象。

面向對象程序設計可以看作一種在程序中包含各種獨立而又互相調用的對象的思想,這與傳統的思想剛好相反:傳統的程序設計主張將程序看作一系列函數的集合,或者直接就是一系列對計算機下達的指令。面向對象程序設計中的每一個(gè)對象都應該能夠接受數據、處理數據并將數據傳達給其它對象,因此它們都可以被看作一個(gè)小型的“機器”,即對象。即把事情交給最適合的對象去做。

面向對象和面向過(guò)程的區別最直觀(guān)的比喻就如:搖(狗尾巴)和 狗.搖尾巴()的區別。

面向對象編程的三個(gè)基本概念:

封裝,面向對象程序設計隱藏了某一方法的具體執行步驟,取而代之的是通過(guò)消息傳遞機制傳送消息給它。經(jīng)過(guò)深入的思考,做出良好的抽象,給出“完整且最小”的接口,并使得內部細節可以對外隱藏

繼承,在某種情況下,一個(gè)類(lèi)會(huì )有“子類(lèi)”。子類(lèi)比原本的類(lèi)(稱(chēng)為父類(lèi))要更加具體化;

多態(tài),指由繼承而產(chǎn)生的相關(guān)的不同的類(lèi),其對象對同一消息會(huì )做出不同的響應;

使用面向對象編程語(yǔ)言,易于構建軟件模型。因為,對象很類(lèi)似乎很容易和現實(shí)世界上的所有事物和概念。

面向對象通過(guò)接口

類(lèi),類(lèi)是相似對象的集合。物以類(lèi)聚——就是說(shuō)明。每個(gè)對象都是其類(lèi)中的一個(gè)實(shí)體。類(lèi)中的對象可以接受相同的消息。換句話(huà)說(shuō):類(lèi)包含和描述了“具有共同特性(數據元素)和共同行為(功能)”的一組對象。

接口,每個(gè)對象都有接口。接口不是類(lèi),而是對符合接口需求的類(lèi)所作的一套規范。接口說(shuō)明類(lèi)應該做什么但不指定如何作的方法。一個(gè)類(lèi)可以有一個(gè)或多個(gè)接口。

方法,方法決定了某個(gè)對象究竟能夠接受什么樣的消息。面向對象的設計有時(shí)也會(huì )簡(jiǎn)單地歸納為“將消息發(fā)送給對象”。

面向對象技術(shù)一方面借鑒了哲學(xué)、心理學(xué)、生物學(xué)的思考方式,另一方面,它是建立在其他編程技術(shù)之上的,是以前的編程思想的自然產(chǎn)物。

如果說(shuō)結構化軟件設計是將函數式編程技術(shù)應用到命令式語(yǔ)言中進(jìn)行程序設計,面向對象編程不過(guò)是將函數式模型應用到命令式程序中的另一途徑,此時(shí),模塊進(jìn)步為對象,過(guò)程龜縮到class的成員方法中。OOP的很多技術(shù)——抽象數據類(lèi)型、信息隱藏、接口與實(shí)現分離、對象生成功能、消息傳遞機制等等,很多東西就是結構化軟件設計所擁有的、或者在其他編程語(yǔ)言中單獨出現。但只有在面向對象語(yǔ)言中,他們才共同出現,以一種獨特的合作方式互相協(xié)作、互相補充。

從上面可以看到,如果按照面向過(guò)程的方法去設計汽車(chē),汽車(chē)廠(chǎng)商需要采購一大堆零件,然后研究如何調試、調用這一大堆零件以完成一個(gè)功能。但是如果采用面向對象的方法去設計汽車(chē),那么汽車(chē)廠(chǎng)商可以采用外包的方式交給專(zhuān)業(yè)的制動(dòng)系統廠(chǎng)商來(lái)設計,只需要約定需要開(kāi)放哪些public方法,輸入什么輸出什么就可以了。

知乎kevin zou總結的三種面向對象方式

靜態(tài)函數包對象

將功能有聯(lián)系的一批函數放在一起封裝成一個(gè)類(lèi)。這種類(lèi)可以完全沒(méi)有內部數據,也可以有數據。當有數據時(shí),這些數據充當的其實(shí)就是配置(配置對于一個(gè)設計優(yōu)秀的對象,是透明的,對象本身內部的函數根本不知道有配置這個(gè)東西,它只知道它需要的每一個(gè)數據在它new之后就已經(jīng)存在this里了,隨取隨用。配置的給予或獲取方式,是構建對象(new)時(shí)才需要去考慮的)這種對象的特點(diǎn)是,它的每一個(gè)函數(或方法)對這些數據都是只讀的,所以不管方法有無(wú)被調用,被誰(shuí)調用,被調用多少次,它也不會(huì )改變它的狀態(tài)。

領(lǐng)域模型對象

這個(gè)概念是相對于傳統的面向數據庫的系統分析和設計而言的。數據庫雖然只用了外鍵就描述了復雜的大千世界,但軟件開(kāi)發(fā)的難點(diǎn)在于適應變化,并且能夠安全地修改。關(guān)系模型看似簡(jiǎn)單,但它卻像一張蜘蛛網(wǎng)一樣將所有table和欄位包在一塊,牽一發(fā)而動(dòng)全身,讓你在修改時(shí)如履薄冰,一不小心就會(huì )顧此失彼,bug此起彼伏。而OO的封裝特性則剛好可以用來(lái)解決這個(gè)問(wèn)題。將業(yè)務(wù)數據整理成一個(gè)個(gè)獨立的對象,讓它們的數據只能被自己訪(fǎng)問(wèn)。留給外界的基本上只是一些接口(方法),數據除非萬(wàn)不得已,一個(gè)都不會(huì )公開(kāi)。外界只能向它發(fā)送消息,它自己則通過(guò)修改自身數據來(lái)響應這種消息。這種對象與第一種對象剛好相反,它一定有數據,而且它的每一個(gè)函數存在的目的就是修改自己的數據。且每一次修改都是粗粒度的,每一次修改后,對象也還是處在valid狀態(tài)。推薦閱讀《領(lǐng)域模型淺析》,《領(lǐng)域模型,你真的理解的了嗎?

順便拓展下:領(lǐng)域驅動(dòng)設計(Domain-Driven Design)-貧血模型-領(lǐng)域模型-充血模型

臨時(shí)對象

其它用來(lái)解決過(guò)程式開(kāi)發(fā)時(shí),超多的變量,超復雜的流程而整理出來(lái)的小對象,。這些對象一起協(xié)作,最后完成一個(gè)傳統成千上萬(wàn)行的過(guò)程式代碼才能完成的功能。例如現在要連接sql server執行查詢(xún)語(yǔ)句并取得結果返回。不使用任何類(lèi)庫和工具,所有步驟都自己進(jìn)行,例如解析協(xié)議,socket網(wǎng)絡(luò )連接,數據包收發(fā)等。這時(shí)候從頭到尾用一個(gè)個(gè)函數來(lái)完成,絕對沒(méi)有先劃分出一個(gè)個(gè)職責分明的對象,讓各對象協(xié)作完成這件事情來(lái)得更簡(jiǎn)單。

但編程實(shí)踐表明,并不是任何東西成為對象都是一件好事情。舉一個(gè)Java中的蹩足的例子:Java中只有對象才能作為參數傳入函數(當然還有原始類(lèi)型primitive type)。所以為了將函數傳遞給另外一個(gè)函數,你需要將函數包裹在一個(gè)對象中,通常會(huì )用一個(gè)匿名類(lèi),因為這個(gè)類(lèi)不會(huì )有其他作用,只是為了讓Java的一切皆為對象的設計高興。

Java擁有純粹的面向對象概念。它從設計之初,就希望以一切皆為對象的純對象模型來(lái)為世界建模。但發(fā)展到現在,Java中加入了越來(lái)越多非對象的東西。引入了閉包,從而獲得了函數式編程中的一級函數;引入泛型,從而獲得了參數化的類(lèi)型。這可能暗示了,這個(gè)世界是如此得豐富多彩,使用單一模式為世界建模并不會(huì )成功。

聲明式編程:

聲明式編程是以數據結構的形式來(lái)表達程序執行的邏輯。它的主要思想是告訴計算機應該做什么,但不指定具體要怎么做。

SQL 語(yǔ)句就是最明顯的一種聲明式編程的例子,例如:

SELECT * FROM collection WHERE num > 5

除了 SQL,網(wǎng)頁(yè)編程中用到的 HTML 和 CSS 也都屬于聲明式編程。

通過(guò)觀(guān)察聲明式編程的代碼我們可以發(fā)現它有一個(gè)特點(diǎn)是它不需要創(chuàng )建變量用來(lái)存儲數據。

另一個(gè)特點(diǎn)是它不包含循環(huán)控制的代碼如 for, while。

函數式編程和聲明式編程是有所關(guān)聯(lián)的,因為他們思想是一致的:即只關(guān)注做什么而不是怎么做。但函數式編程不僅僅局限于聲明式編程。

函數式編程

函數式編程(functional programming)或稱(chēng)函數程序設計、泛函編程,是一種編程范式,它將計算機運算視為函數運算,并且避免使用程序狀態(tài)以及易變對象。其中,λ演算(lambda calculus)為該語(yǔ)言最重要的基礎。而且,λ演算的函數可以接受函數當作輸入(引數)和輸出(傳出值)。

函數式編程關(guān)心類(lèi)型(代數結構)之間的關(guān)系,命令式編程關(guān)心解決問(wèn)題的步驟。函數式編程中的lambda可以看成是兩個(gè)類(lèi)型之間的關(guān)系,一個(gè)輸入類(lèi)型和一個(gè)輸出類(lèi)型。lambda演算就是給lambda表達式一個(gè)輸入類(lèi)型的值,則可以得到一個(gè)輸出類(lèi)型的值,這是一個(gè)計算,計算過(guò)程滿(mǎn)足 -等價(jià)和 -規約。函數式編程的思維就是如何將這個(gè)關(guān)系組合起來(lái),用數學(xué)的構造主義將其構造出你設計的程序

比起命令式編程,函數式編程更加強調程序執行的結果而非執行的過(guò)程,倡導利用若干簡(jiǎn)單的執行單元讓計算結果不斷漸進(jìn),逐層推導復雜的運算,而不是設計一個(gè)復雜的執行過(guò)程。

命令式編程是面向計算機硬件的抽象,有變量(對應著(zhù)存儲單元),賦值語(yǔ)句(獲取,存儲指令),表達式(內存引用和算術(shù)運算)和控制語(yǔ)句(跳轉指令),一句話(huà),命令式程序就是一個(gè)馮諾依曼機的指令序列。

函數式編程是面向數學(xué)的抽象,將計算描述為一種表達式求值,一句話(huà),函數式程序就是一個(gè)表達式。

函數式編程最重要的特點(diǎn)是“函數第一位”,即函數可以出現在任何地方,比如你可以把函數作為參數傳遞給另一個(gè)函數,不僅如此你還可以將函數作為返回值。

函數式編程的本質(zhì)

函數式編程中的函數這個(gè)術(shù)語(yǔ)不是指計算機中的函數(實(shí)際上是Subroutine),而是指數學(xué)中的函數,即自變量的映射。也就是說(shuō)一個(gè)函數的值僅決定于函數參數的值,不依賴(lài)其他狀態(tài)。比如sqrt(x)函數計算x的平方根,只要x不變,不論什么時(shí)候調用,調用幾次,值都是不變的。

在函數式語(yǔ)言中,函數作為一等公民,可以在任何地方定義,在函數內或函數外,可以作為函數的參數和返回值,可以對函數進(jìn)行組合。

純函數式編程語(yǔ)言中的變量也不是命令式編程語(yǔ)言中的變量,即存儲狀態(tài)的單元,而是代數中的變量,即一個(gè)值的名稱(chēng)。變量的值是不可變的(immutable),也就是說(shuō)不允許像命令式編程語(yǔ)言中那樣多次給一個(gè)變量賦值。比如說(shuō)在命令式編程語(yǔ)言我們寫(xiě)“x = x + 1”,這依賴(lài)可變狀態(tài)的事實(shí),拿給程序員看說(shuō)是對的,但拿給數學(xué)家看,卻被認為這個(gè)等式為假。

函數式語(yǔ)言的如條件語(yǔ)句,循環(huán)語(yǔ)句也不是命令式編程語(yǔ)言中的控制語(yǔ)句,而是函數的語(yǔ)法糖,比如在Scala語(yǔ)言中,if else不是語(yǔ)句而是三元運算符,是有返回值的。

嚴格意義上的函數式編程意味著(zhù)不使用可變的變量,賦值,循環(huán)和其他命令式控制結構進(jìn)行編程。

從理論上說(shuō),函數式語(yǔ)言也不是通過(guò)馮諾伊曼體系結構的機器上運行的,而是通過(guò)λ演算來(lái)運行的,就是通過(guò)變量替換的方式進(jìn)行,變量替換為其值或表達式,函數也替換為其表達式,并根據運算符進(jìn)行計算。λ演算是圖靈完全(Turing completeness)的,但是大多數情況,函數式程序還是被編譯成(馮諾依曼機的)機器語(yǔ)言的指令執行的。

函數式編程的特性

  • 函數是"一等公民":函數優(yōu)先,和其他數據類(lèi)型一樣。

  • 只用"表達式",不用"語(yǔ)句":通過(guò)表達式(expression)計算過(guò)程得到一個(gè)返回值,而不是通過(guò)一個(gè)語(yǔ)句(statement)修改某一個(gè)狀態(tài)。

  • 無(wú)副作用:不污染變量,同一個(gè)輸入永遠得到同一個(gè)數據。

  • 不可變性:前面一提到,不修改變量,返回一個(gè)新的值。

由于變量值是不可變的,對于值的操作并不是修改原來(lái)的值,而是修改新產(chǎn)生的值,原來(lái)的值保持不便。通常來(lái)說(shuō),算法都有遞推(iterative)和遞歸(recursive)兩種定義。

由于變量不可變,純函數編程語(yǔ)言無(wú)法實(shí)現循環(huán),這是因為For循環(huán)使用可變的狀態(tài)作為計數器,而While循環(huán)或DoWhile循環(huán)需要可變的狀態(tài)作為跳出循環(huán)的條件。因此在函數式語(yǔ)言里就只能使用遞歸來(lái)解決迭代問(wèn)題,這使得函數式編程嚴重依賴(lài)遞歸。

函數式語(yǔ)言當然還少不了以下特性:

  • 高階函數(Higher-order function):就是參數為函數或返回值為函數的函數。有了高階函數,就可以將復用的粒度降低到函數級別,相對于面向對象語(yǔ)言,復用的粒度更低。

  • 偏應用函數(Partially Applied Functions):一個(gè)函數接收一個(gè)有多個(gè)參數的函數,返回一個(gè)需要較少參數的函數。偏函數將一到多個(gè)參數在內部固定,然后返回新函數,返回的函數接收剩余的參數完成函數的應用。

  • 柯里化(Currying):輸入一個(gè)有多個(gè)參數的函數, 返回一個(gè)只接收單個(gè)參數的函數。

  • 閉包(Closure):閉包就是有權訪(fǎng)問(wèn)另一個(gè)函數作用域中變量的函數.閉包的三個(gè)特性:1.閉包是定義在函數中的函數 。2.閉包能訪(fǎng)問(wèn)包含函數的變量。3.即使包含函數執行完了, 被閉包引用的變量也得不到釋放。具體參看《閑話(huà)閉包

    函數式編程的好處

    由于命令式編程語(yǔ)言也可以通過(guò)類(lèi)似函數指針的方式來(lái)實(shí)現高階函數,函數式的最主要的好處主要是不可變性帶來(lái)的。沒(méi)有可變的狀態(tài),函數就是引用透明(Referential transparency)的和沒(méi)有副作用(No Side Effect)。

函數即不依賴(lài)外部的狀態(tài)也不修改外部的狀態(tài),函數調用的結果不依賴(lài)調用的時(shí)間和位置,這樣寫(xiě)的代碼容易進(jìn)行推理,不容易出錯。這使得單元測試和調試都更容易。

由于(多個(gè)線(xiàn)程之間)不共享狀態(tài),不會(huì )造成資源爭用(Race condition),也就不需要用鎖來(lái)保護可變狀態(tài),也就不會(huì )出現死鎖,這樣可以更好地并發(fā)起來(lái),尤其是在對稱(chēng)多處理器(SMP)架構下能夠更好地利用多個(gè)處理器(核)提供的并行處理能力。

我覺(jué)得函數編程的好處就不用管js里面該死的this指向

函數式編程語(yǔ)言還提供惰性求值-Lazy evaluation,也稱(chēng)作call-by-need,是在將表達式賦值給變量(或稱(chēng)作綁定)時(shí)并不計算表達式的值,而在變量第一次被使用時(shí)才進(jìn)行計算。這樣就可以通過(guò)避免不必要的求值提升性能。

函數式編程語(yǔ)言一般還提供強大的模式匹配(Pattern Match)功能。在函數式編程語(yǔ)言中可以定義代數數據類(lèi)型(Algebraic data type),通過(guò)組合已有的數據類(lèi)型形成新的數據類(lèi)型,如在Scala中提供case class,代數數據類(lèi)型的值可以通過(guò)模式匹配進(jìn)行分析。

函數式編程天生親和單元測(特別是黑盒測試),因為FP關(guān)注就是輸入與輸出。反觀(guān)Java或者C++,僅僅檢查函數的返回值是不夠的:代碼可能修改外部狀態(tài)值,因此我們還需要驗證這些外部的狀態(tài)值的正確性。在FP語(yǔ)言中呢,就完全不需要。

調試查錯方面,因為FP程序中的錯誤不依賴(lài)于之前運行過(guò)的不相關(guān)的代碼。而在一個(gè)指令式程序中,一個(gè)bug可能有時(shí)能重現而有些時(shí)候又不能。因為這些函數的運行依賴(lài)于某些外部狀態(tài), 而這些外部狀態(tài)又需要由某些與這個(gè)bug完全不相關(guān)的代碼通過(guò)某個(gè)特別的執行流程才能修改。在FP中這種情況完全不存在:如果一個(gè)函數的返回值出錯了,它一直都會(huì )出錯,無(wú)論你之前運行了什么代碼。而整個(gè)程序就是函數接龍。

推薦閱讀《傻瓜函數式編程

泛型編程

泛型編程是另外一個(gè)有趣的話(huà)題。泛型為程語(yǔ)言提供了更高層級的抽象,即參數化類(lèi)型。換句話(huà)說(shuō),就是把一個(gè)原本特定于某個(gè)類(lèi)型的算法或類(lèi)當中的類(lèi)型信息抽象出來(lái)。這個(gè)抽象出來(lái)的概念在C++的STL(Standard Template Library)中就是模版(Template)。STL展示了泛型編程的強大之處,一出現就成為了C++的強大武器。除C++之外,C#,Java,Haskell等編程語(yǔ)言都引入了泛型概念。

泛型編程是一個(gè)稍微局部一些的概念,它僅僅涉及如何更抽象地處理類(lèi)型,即參數化類(lèi)型。這并不足以支撐起一門(mén)語(yǔ)言的核心概念。我們不會(huì )聽(tīng)到一個(gè)編程語(yǔ)言是純泛型編程的,而沒(méi)有其他編程范式。但正因為泛型并不會(huì )改變程序語(yǔ)言的核心,所以在大多數時(shí)候,它可以很好的融入到其他的編程方式中。C++,Scala,Haskell這些風(fēng)格迥異的編程語(yǔ)言都支持泛型。泛型編程提供了更高的抽象層次,這意味著(zhù)更強的表達能力。這對大部分編程語(yǔ)言來(lái)說(shuō)都是一道美味佐餐美酒。

在Swift中,泛型得到廣泛使用,許多Swift標準庫是通過(guò)泛型代碼構建出來(lái)的。例如Swift的數組和字典類(lèi)型都是泛型集。這樣的例子在Swift中隨處可見(jiàn)。

參考文章:

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Julia機器學(xué)習核心編程.3
怎么理解函數式編程思維?
主流編程語(yǔ)言?xún)?yōu)劣考
漫談響應式編程 | 代碼灣
編程范式,程序員的編程世界觀(guān)
計算機編程的歷史演進(jìn):用 50 種編程語(yǔ)言寫(xiě)“Hello,World!”程序
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久