強類型、弱類型、靜態類型、動態類型語言

強類型與弱類型語言

強類型語言

1974年,兩位美國計算機科學家Liskov,Zilles提出強類型語言的概念。java

在強類型語言中,當一個對象從調用函數傳遞到被調用函數時,其類型必須與被調用函數中聲明的類型兼容c++

function A(){
    B(x)
}
function B(y){
    // y能夠被賦值x,程序運行良好
}
複製代碼

這是一個較爲寬泛的定義,並無闡述具體的規則,後人對強類型語言的定義則會更精確一些。瀏覽器

強類型語言:不容許改變變量的數據類型,除非進行強制類型轉換。bash

以java爲例函數

public class HelloWorld {
    public static void main(String []args) {
	int x =1;
	boolean y = true;
	x = y;
        System.out.println(x);
    }
}
複製代碼

定義x爲數字,y爲布爾值,將y賦值給x,會報錯。工具

public class HelloWorld {
    public static void main(String []args) {
	int x =1;
	char y = 'a'
	x = y;
        System.out.println(x);   // 97
    }
}
複製代碼

定義x爲數字,y爲字符,將y賦值給x,最終值爲97,Java在這裏進行了強制類型轉換,將字符a的ASCll碼賦值給了x,這樣x的數據類型依舊是整型。性能

弱類型語言

弱類型語言:變量能夠被賦予不一樣的值單元測試

仍然是剛纔的例子,在瀏覽器中用js來運行。測試

能夠看到,x的類型變成了它被賦值的那個變量的類型。

總而言之,強類型語言對變量的類型的轉換有嚴格的限制,除非進行強制類型轉換,不一樣類型的變量是不能相互賦值的,這樣就能夠避免一些低級錯誤。而弱類型語言就沒有什麼約束,能夠很靈活地進行類型轉換,但也更容易產生bug。ui

靜態類型語言與動態類型語言

靜態類型語言:在編譯階段肯定全部變量的類型。
動態類型語言:在執行階段肯定全部變量的類型。

用一個例子來講明:

class C {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}

function add(a) {
    return a.x + a.y;
}

var c1 = new C(10, 20);
var c2 = new C('hello', 'world');

console.log(add(c1));  // 30
console.log(add(c2));  // helloworld
複製代碼

定義一個類C,併爲它添加了兩個屬性x和y,而後定義了一個add函數,用來把一個實例的全部屬性相加。當JS編譯器看到這段代碼時,它徹底不知道add函數裏的參數a的類型是什麼,只有執行的時候才知道。最終c1是數字相加,c2是字符串拼接。

一樣的代碼,用c++實現

class C {
    public;
        int x;
        int y;
}

int add(C a) {
    return a.x + a.y;
}
複製代碼

在編譯的時候,就知道C裏面的屬性x和y的類型是整型了。

從內存分配的角度來看上面的例子,c++因爲一開始就定義好了屬性類型是整型,因此假設x是基地址,那麼y就在基地址+4的位置上。js則不一樣,因爲一開始不知道屬性類型,因此也不知道每一個屬性要佔多少地址空間,因此須要額外的空間存儲屬性名,在程序運行時,再動態計算屬性的地址偏移量。

由此看來,動態類型語言在空間佔用上會有一些損耗。

總結一下二者的區別

靜態類型語言     動態類型語言    
對類型檢查嚴格 對類型檢查寬鬆
當即發現錯誤 BUG不易被發現
運行性能較好 運行性能較差
自文檔化 可讀性較差

但動態類型語言也有方法來補救這些缺點,好比,

  • 性能是能夠改善的(V8引擎),語言的靈活性不可或缺
  • 隱藏的錯誤能夠經過單元測試發現
  • 文檔經過工具生成

因此雖然js是一門動態弱類型語言,但它倒是目前最流行的語言之一,就是由於它的靈活和應用場景普遍。

最後,看一下各類語言的強弱類型和動態靜態類型吧。

相關文章
相關標籤/搜索