編程語(yǔ)言的類型系統(tǒng)簡(jiǎn)介

簡(jiǎn)介

類型指一個(gè)編程語(yǔ)言中的數(shù)值、表達(dá)式、函數(shù)和模塊等等屬性內(nèi)容。類型系統(tǒng)包括如何定義這些不同類型,如何操作這些類型,這些類型如何相互作用等方面內(nèi)容。類型系統(tǒng)最主要的作用是通過(guò)檢查每個(gè)值的類型和這些值得流動(dòng)的規(guī)則來(lái)減少類型錯(cuò)誤的發(fā)生。檢查可以是靜態(tài)的(at compile time), 也可以是動(dòng)態(tài)的(at run time),或者是兩者的結(jié)合。類型系統(tǒng)也有些其他的作用,比如編譯器優(yōu)化等。

類型系統(tǒng)是編程語(yǔ)言的一部分,經(jīng)常被嵌入到解釋器和編譯器中。它也被一些靜態(tài)檢查工具所使用。

類型錯(cuò)誤產(chǎn)生原因

計(jì)算機(jī)的硬件層面是無(wú)法區(qū)分內(nèi)存地址、指令碼、字符、整數(shù)、浮點(diǎn)數(shù)的,在硬件層面這些都是bit。類型化就是賦予這些bit意義,哪些是內(nèi)存中的值,哪些是一些變量等等。這樣能讓編程者在更高層次思考,而不用關(guān)心比特和字節(jié)。但每種類型所占用的bit數(shù),和作用都是不同的,如果互相之間賦值移動(dòng)不當(dāng),就會(huì)造成類型錯(cuò)誤。

類型檢查

如果一個(gè)語(yǔ)言的編譯器引入越多的類型檢查的限制,就可以稱這個(gè)語(yǔ)言的類型檢查越強(qiáng)。反之越弱。舉個(gè)例子,A語(yǔ)言的編譯器可能在編譯時(shí)會(huì)認(rèn)為 3 / "Hello, World"是無(wú)效的,而B(niǎo)語(yǔ)言不會(huì),等到運(yùn)行到這塊代碼時(shí)發(fā)現(xiàn)無(wú)法執(zhí)行才會(huì)認(rèn)為此處無(wú)效。那明顯A語(yǔ)言比B語(yǔ)言更強(qiáng)。強(qiáng)/弱類型語(yǔ)言目前業(yè)界沒(méi)有統(tǒng)一的定義,只能說(shuō)哪種語(yǔ)言更強(qiáng)或者更弱一些。

靜態(tài)類型檢查

靜態(tài)類型檢查是基于編譯器來(lái)分析源碼本身來(lái)確保類型安全,比如不會(huì)出現(xiàn)上面的整形除以字符串的情況。靜態(tài)類型檢查能讓很多bug在開(kāi)發(fā)早起被捕捉到,并且它也能優(yōu)化運(yùn)行。因?yàn)槿绻幾g器在編譯時(shí)已經(jīng)證明程序是類型安全的,就不用在運(yùn)行時(shí)進(jìn)行動(dòng)態(tài)的類型檢查,編譯過(guò)后的代碼會(huì)更優(yōu)化,運(yùn)行更快。

但對(duì)于一個(gè)圖靈完備的語(yǔ)言,靜態(tài)檢查有時(shí)可能偏于保守。比如:

if <test> then <do something> else <error code>

即使test永遠(yuǎn)為true,對(duì)于很多靜態(tài)檢查的語(yǔ)言也會(huì)認(rèn)為以上代碼有問(wèn)題,因?yàn)殪o態(tài)分析很難判斷else的部分是否可以拿掉。不但如此,有些編程技術(shù)也是無(wú)法通過(guò)靜態(tài)方式檢查出來(lái)的,比如Java中的向下轉(zhuǎn)型(downcasting,父類對(duì)象向下轉(zhuǎn)為具體的子類對(duì)象,一種不安全操作)。

所以很多語(yǔ)言會(huì)同時(shí)使用靜態(tài)檢查和動(dòng)態(tài)檢查,靜態(tài)證明可以,動(dòng)態(tài)確定其他部分。有些語(yǔ)言還會(huì)讓開(kāi)發(fā)者選擇用靜態(tài)或者動(dòng)態(tài)類型安全檢查,如C#就卻別了靜態(tài)類型和動(dòng)態(tài)類型變量。而有些語(yǔ)言運(yùn)行開(kāi)發(fā)者寫一些非類型安全的代碼,比如C語(yǔ)言允許開(kāi)發(fā)者把值在任意兩個(gè)長(zhǎng)度一樣的類型間強(qiáng)制轉(zhuǎn)換。

靜態(tài)類型如:Java、C、Swift、Pascal等。更多

動(dòng)態(tài)類型檢查

動(dòng)態(tài)類型檢查是在程序運(yùn)行時(shí)進(jìn)行的。很多類型安全的語(yǔ)言也都包括一些動(dòng)態(tài)類型檢查。動(dòng)態(tài)檢查可能會(huì)導(dǎo)致一些運(yùn)行時(shí)錯(cuò)誤,有些語(yǔ)言會(huì)從錯(cuò)誤中恢復(fù),有些會(huì)導(dǎo)致fatal error。

編程語(yǔ)言中,把只有動(dòng)態(tài)類型檢查沒(méi)有靜態(tài)類型檢查的語(yǔ)言稱為“動(dòng)態(tài)類型語(yǔ)言”。

例如:Ruby、PHP、Objective-C、Perl、Python、JavaScript、Lisp等。更多

類型安全和內(nèi)存安全

這兩者是另一種區(qū)別語(yǔ)言種類的方法。計(jì)算機(jī)科學(xué)家將不允許操作和轉(zhuǎn)化違反類型系統(tǒng)規(guī)則的語(yǔ)言稱為類型安全語(yǔ)言;將不允許訪問(wèn)未被分配內(nèi)存的語(yǔ)言稱為內(nèi)存安全語(yǔ)言,比如,一個(gè)內(nèi)存安全語(yǔ)言會(huì)檢查數(shù)組越界問(wèn)題。

C語(yǔ)言既不是類型安全也不是內(nèi)存安全的語(yǔ)言,如下代碼:

int x = 5;
char y[] = "37";
char* z = x + y;

這樣讓z指向了y地址加5的地址,可能包含了垃圾數(shù)據(jù),既訪問(wèn)了未分配的內(nèi)存,也產(chǎn)生不同類型間的不安全轉(zhuǎn)換。

參考文獻(xiàn):
https://en.wikipedia.org/wiki/Type_system?oldformat=true

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容