強/弱類型、動/靜類型、GC 和 VM,你真的分清楚了麼?

強類型 Vs. 弱類型

  • 強和弱是一個相對的概念,強是指傾向於將未定義的行爲視做錯誤(Java、Python),弱是指傾向於進行隱式的轉換、忽略類型相關的錯誤(JavaScript)。
  • 不少設計得不夠嚴謹的語言,雖然大多數狀況下(或者咱們一般鼓勵你們這麼作)是強類型的,但也有弱類型的部分(PHP)
  • 還有的語言由於提供的抽象能力很弱,咱們不得不去用弱類型的部分(C)
  • 鴨子類型(duck typing)是強弱類型的一個折中(常見於動態類型中,例如 Python),兼顧了靈活性和嚴謹性。
  • 咱們認爲弱類型是爲了方便,而強類型是爲了儘早發現錯誤。

動態類型 Vs. 靜態類型

  • 靜態類型的變量的類型是在編譯時肯定的(C++、Java);動態類型的類型是在運行時肯定的(JavaScript、Python),例如你能夠在一個 if 的兩個分支裏給一個變量賦值不一樣的類型。
  • 有的動態類型語言也會添加編譯期的類型檢查(TypeScript、Python),但由於語言自己的動態性,這些檢查僅能覆蓋一部分狀況。
  • 在動態類型的語言中由於類型不那麼重要,因此不少時候甚至沒有提供指定類型的語法(隱含了運行時的自動推導);而在靜態類型語言裏一般須要爲變量指定類型,因此纔有了編譯期自動類型推導來提供便利,而動態類型語言則作不到這一點(由於不能在編譯期肯定類型,更無從推導)。
  • 咱們認爲靜態類型有助於在編譯時發現有關類型的錯誤,肯定的類型也給了編譯期更多的優化空間;而動態類型給了開發者更高的靈活度。

垃圾回收 Vs. 無垃圾回收

  • 無 GC 是指代碼必須自行管理申請到的內存並在恰當的時機釋放(Rust、C/C++);而有 GC 的語言會經過引用計數(PHP<5.3)、標記複製(V8)等方式按期查找無用的內存進行釋放。
  • 標記複製的 GC 的過程一般會引發線程的暫停,也會花費額外的 CPU;但 GC 對於創建高層次的抽象又是必不可少的:異常、閉包等(雖然 C++ 在無 GC 的狀況下也實現了這兩個特性,但也引入了很是高的複雜度)。
  • 咱們認爲有 GC 能夠簡化對內存的管理,創建複雜的抽象;而無 GC 能夠獲得更底層的對內存的控制,帶來更好的性能,避免由於 GC 形成的卡頓。

虛擬機 VS. 本地代碼

  • 虛擬機是指在語言和 CPU 之間還有一個用於進行翻譯的層次(JavaScript、Java);無虛擬機是指編譯器直接生成本地代碼給 CPU 執行(C/C++、Golang)。
  • 虛擬機也提供了更爲複雜的運行時的動態特性,但這些特性有的時候也能夠在沒有虛擬機的狀況下實現(例如 C++ 的運行時類型識別、Go 的 GC)。
  • 虛擬機能夠以解釋的方式執行(Python,將代碼視做一種數據指令來執行),也能夠即時編譯(JIT)的方式來執行(V8,先將代碼編譯到本地代碼而後執行),有時也會混合這兩種方式(爲了更快的啓動速度)。
  • 咱們認爲無虛擬機的語言能夠在更低的層次和其餘程序交互,同時也自然地有着更好的性能;而有虛擬機的語言則能夠輕鬆地跨平臺,針對特定的架構在運行時即時編譯出更高性能的代碼。

小結

語言 強類型 動態類型 垃圾回收 虛擬機
C
C++ Y
Java Y Y Y
Python Y Y Y Y
JavaScript Y Y Y
PHP Y Y Y
Golang Y Y
Rust Y

參考來源:閉包

相關文章
相關標籤/搜索