編程語言有不少種流派和思想,有一些編程語言同時支持多種編程範式。前端
採用靜態類型編程範式的編程語言,其變量須要明確指定類型。表明語言:C,C++,Pascal,Objective-C,Java,C#,VB.NET,Swif,Golang。程序員
一、編譯器能夠在編譯時就能找出類型錯誤。算法
二、編譯器編譯時知道類型信息,就能夠提升性能。編程
這種範式認爲,程序員確定知道變量的類型,你丫要是不知道變量的類型,那你就別混了!編譯時,程序會報錯。數據結構
Swift和Go語言都是靜態類型編程語言,但它們都不須要明確指定類型,而是能夠經過推斷由編譯器自動肯定其類型。閉包
採用靜態類型編程範式的編程語言,其變量不須要明確指定類型。任意變量,能夠指向任意類型的對象。表明語言:Python,Ruby,JavaScript。併發
動態類型的哲學能夠用鴨子類型(英語:ducktyping)這個概念來歸納。JamesWhitcombRiley提出的鴨子測試能夠這樣表述:「當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就能夠被稱爲鴨子。」框架
這種範式認爲,程序員確定知道變量的類型和它支持的方法和屬性,你丫要是不知道變量的類型,那你就別混了!運行時程序會崩潰!程序崩潰怨誰?怨你本身唄,你不是合格的程序員!編程語言
不須要明肯定義接口和抽象類型。只要一個類型支持須要的方法和屬性,那麼就OK。程序會至關靈活和簡單。C++,Java,C#視之爲命脈的接口/基類,在動態語言這裏都視如無物!模塊化
一、若是類型不對,編譯器也沒法找到錯誤,而是運行時程序崩潰。
二、由於編譯器不知道變量的類型,所以沒法優化性能。
面向對象編程範式,從上世紀70年代末開始興起。它支持類和類的實例做爲封裝代碼的模塊。表明語言:Smalltalk,C++,Objective-C,Java,C#,VB.NET,Swift,Go,Python,Ruby,ActionScritp,OCaml.
早期編程語言都是面向過程的。就是順序,條件,循環,構成一個個函數。隨着代碼規模的增大,人們發現有必要對代碼進行模塊化。一個概念對應的代碼放在一個文件中,這樣便於併發開發和進行代碼管理。
人們還發現了「程序=數據結構+算法」的規律。所以,一個概念對應的數據結構和函數應該放在一個文件中。這就是類的概念。
面向對象編程範式,確實極大地提升了生產效率,所以獲得了普遍的應用,所以在語言層面支持面向對象編程範式的語言是極多的。
C語言儘管在語言層面上並不支持面向對象編程範式,但現代的C語言開發都會應用面向對象的模塊化思想,把同一類的數據結構和函數放在一個文件中,採用相似的命名方式。
畢竟C語言沒有在語言層面上支持面向對象,所以就有不少程序員想給C語言添加面向對象支持。其中的表明是C++和Objective-C。
C++是一種新的語言,但大部分語言元素是和C兼容的。
Objective-C是徹底兼容的C的。Objective-C是給C添加了薄薄的一層語法糖以支持接口(就是其餘語言的類)和協議(就是其餘語言的接口)。甚至,Objective-C一開始的實現,就是一個C語言的預編譯器。Objective-C坦白講,除了添加的語法不太符合C流外,實際上其面向對象系統設計是至關精妙的。喬布斯早年慧眼識珠,把Objective-C收人囊中,由於封閉於Apple/NextStep系統內,所以少有人知。隨着iOs系統的普及,Objective-C近幾年才名滿天下。
函數式編程範式,是一些數學家發明的編程語言,他們認爲程序就是數學函數嘛。表明語言:Lisp,Erlang,JavaScript,OCaml,Prog。
有不少大牛極力鼓吹過函數式編程語言,認爲其極具革命性。但我認爲他們太高估計了函數式編程範式的威力,我並不認爲函數式編程範式相對於面向對象編程範式有何高明之處。
函數式編程語言,核心就是函數,它們沒有Class類的概念。但它的函數又不是傳統面向過程語言的函數,它的函數支持「閉包」的概念。
在我看來,函數式編程語言的函數,也就是「閉包」,說白了,其實就是「類」。編程語言發展到今天,就是須要模塊化,就是須要把「數據結構」和「算法」結合起來。不論何種語言,不把它們結合起來的編程方式,都是沒有出路的。
面向對象編程語言,用類把「數據結構」和「算法」結合起來。類的核心是「數據結構」,也就是其「屬性」,而不是「算法」,其「函數」。在類中,是函數依附於屬性。
而函數式編程語言,用閉包把「數據結構」和「算法」結合起來。是函數可以抓取外部的字段。是「屬性」依附於「函數」。
「類」本質上和「閉包」是等價的。如今不少面向對象編程語言都加上了對閉包的支持。觀察其代碼,咱們能夠發現,它們實際上都是用「類」來實現「閉包」的。
「類」和「閉包」誰更易用?明顯是「類」。
而「閉包」更簡潔一些,所以「閉包」在面向對象編程語言中經常使用來替換匿名類。只有一個函數的類,寫成一個類太麻煩,不如寫成閉包,更加簡潔。
吐槽一下OCaml語言,其前身Caml語言自己是一種挺好的函數式語言,硬生生添加了一套完整的面向對象機制,同時支持面向對象和函數式編程範式,很容易像C++同樣腦裂的。
也有不少面嚮對象語言控看着JavaScript嫌煩,老是想把面向對象支持添加到JavaScript上。ActionScript就是其中一種嘗試。我用過,真的是和Java沒多少區別了。
再吐槽一下ExtJS。當初選型Web前端開發框架時比較了ExtJS和JQuery。
ExtJS明顯是Java高手開發的,硬生生用JavaScript模擬Swing的設計思想,搞了一套UI庫。
JQuery開發者明顯是領悟了JavaScript的函數式編程範式,依據JavaScript的動態函數式編程語言的特色打造了一套UI庫,馬上秒殺ExtJS。
由ExtJS和JQuery的故事,咱們能夠看到多語言編程能力是多麼的重要。ExtJS的做者精通並喜好Java,所以他把手術刀JavaScript當作錘子Java使,一通亂敲,費力不討好。
函數式編程語言,還有尾遞歸等一些小技巧。尾遞歸能夠不用棧,防止遞歸調用時棧溢出。
模板編程,就是把類型做爲參數,一套函數能夠支持任意多種類型。表明語言:C++。
模板編程的需求,是在C++開發容器庫的時候發明的。由於容器須要保存任意類型的對象,所以就有了泛型的需求。
C++的模板編程,是在編譯時,根據源碼中的使用狀況,建立對應類型的代碼。除了C++這種方式,Java,C#也有相似的機制,叫作「泛型」,但它們的實現方式和C++的模板很不一樣。它們的編譯器不會生成新的代碼,而是使用強制類型轉換的方式實現。
在沒有模板/泛型的編程語言中,怎樣在容器中存放對象呢?存取公共基類類型(Java,C#)的對象,或者void*指針(C)便可,取出時本身強制類型轉換爲實際類型。動態類型語言,不關心類型,更是無所謂了,隨便什麼對象直接往容器裏扔進去,取出來直接用便可。
一些C++高手又在模板的基礎上搞出了「模板元編程」。由於模板編程,就是C++的編譯器搞定的嘛,模板元編程就是讓編譯器運算,編譯完結果也就算出來了。我不知道除了研究和炫技,這玩意有啥用?
一門語言是否值得學 習,我認爲有幾個標準:
一、是否要用,要用就得學,這麼沒有疑問的。畢竟咱們都要吃飯的嘛。
二、其語言特性是否給你耳目一新的感受。若是是,那就值回票價了。如Go語言廢掉了異常,改用返回多值。我深覺得然。我其實已經主動不用異常好多年了。由於,我以爲既然C不支持異常也活得很好,爲何須要異常呢?出錯了,返回錯誤碼。沒法挽回的錯誤,直接Abort程序就能夠嘛!並且,異常其實是違反面向過程編程原則的。一個函數應該只有一個入口一個出口。拋出異常就多了出口了。
三、是否擅長某一個領域。若是你手裏只有一把錘子,那麼你就只能把全部任務都當作釘子猛錘一通。但若是工具箱裏有多種工具,那面對不一樣的任務就駕輕就熟多了。