隨著互聯網編程技術的不斷發展,現在大多數的軟件開發都是通過編程語言來實現的,今天我們就壹起來了解壹下C語言編程開發技術都有哪些優勢和劣勢。
C語言的壹些好的體驗
壹次通過閱讀POV-Ray源代碼學會如何在C語言中實現面向對象編程。
通過閱讀GTK+源代碼了解C語言代碼的清晰、幹凈和可維護性。
通過閱讀SIOD和Guile的源代碼,知道如何使用C語言實現Scheme解析器。
使用C語言寫出GNOMEEye的初始版本,並對MicroTile渲染進行調優。
C語言的壹些不好的體驗
在Evolution團隊時,很多東西老是崩潰。那個時候還沒有Valgrind,為了得到Purify這個軟件,需要購買壹臺Solaris機器。
調試gnome-vfs線程死鎖問題。
調試Mesa,卻無果。
接手Nautilus-share的初始版本,卻發現代碼裏面居然沒有使用free()。
想要重構代碼,卻不知道該如何管理好內存。
想要打包代碼,卻發現到處是全局變量,而且沒有靜態函數。
但不管怎樣,還是來說說那些Rust裏有但C語言裏沒有的東西吧。
自動資源管理
Rust從C++那裏借鑒了壹些想法,如RAII(ResourceAcquisitionIsInitialization,資源獲取即初始化)和智能指針,並加入了值的單壹所有權原則,還提供了自動化的決策性資源管理機制。
自動化:不需要手動調用free()。內存使用完後會自動釋放,文件使用完後會自動關閉,互斥鎖在作用域之外會自動釋放。如果要封裝外部資源,基本上只要實現Drop這個trait就可以了。封裝過的資源就像是編程語言的壹部分,因為妳不需要去管理它的生命周期。
決策性:資源被創建(內存分配、初始化、打開文件等),然後在作用域之外被銷毀。根本不存在垃圾收集這回事:代碼執行完就都結束了。程序數據的生命周期看起來就像是函數調用樹。
如果在寫代碼時老是忘記調用這些方法(free/close/destroy),或者發現以前寫的代碼已經忘記調用,甚至錯誤地調用,那麽以後我再也不想使用這些方法了。
泛型
Vec真的就是元素T的vector,而不只是對象指針的數組。在經過編譯之後,它只能用來存放類型T的對象。
在C語言裏需要些很多代碼才能實現類似的功能,所以我不想再這麽幹了。
trait不只是interface
Rust並不是壹門類似那樣的面向對象編程語言,它有trait,看起來就像是裏的interface——可以用來實現動態綁定。如果壹個對象實現了Drawable,那麽就可以肯定該對象帶有draw()方法。
不過不管怎樣,trait的威力可不止這些。
依賴管理
以前實現依賴管理需要:
手動調用或通過自動化工具宏來調用g-config。
指定頭文件和庫文件路徑。
基本上需要人為確保安裝了正確版本的庫文件。
而在Rust裏,只需要編寫壹個Cargo.toml文件,然後在文件裏指明依賴庫的版本。這些依賴庫會被自動下載下來,或者從某個指定的地方獲取。
測試
C語言的單元測試非常困難,原因如下:
內部函數通常都是靜態的。也就是說,它們無法被外部文件調用。測試程序需要使用#include指令把源文件包含進來,或者使用#ifdefs在測試過程中移除這些靜態函數。
需要編寫Makefile文件將測試程序鏈接到其中的部分依賴庫或部分代碼。
需要使用測試框架,並把測試用例註冊到框架上,還要學會如何使用這些框架。
衛生宏(HygienicMacro)
Rust的衛生宏避免了C語言宏可能存在的問題,比如宏中的壹些東西會掩蓋掉代碼裏的標識符。Rust並不要求宏中所有的符號都必須使用括號,比如max(5+3,4)。
沒有自動轉型
在C語言裏,北京北大青鳥發現很多bug都是因為在無意中將int轉成short或char而導致,而在Rust裏就不會出現這種情況,因為它要求顯示轉型。
不會出現整型溢出
這個就不用再多作解釋了。