Golang本身是用什麼語言寫的?
我看golang的發展歷史說
2015年8月19日,Go語言Go 1.5版發布,本次更新中移除了」最後殘餘的C代碼」
然後看了一下golang的官方倉庫的make文件好像在編譯的時候調用了/bin/go,以及源碼裡面有個src/go目錄,裡面有一些ast相關的代碼,那麼新版本的golang都是用golang本身編譯的嗎?我好像繞入了雞生蛋蛋生雞的問題中了。話說最早以前golang是用什麼寫的呢?
是的Go是自舉的。
新語言誕生過程:
當年Go語言使用C語言設計的編譯器來編譯Go語言編譯器,
發現Go特性優秀值得繼續干,編寫測試用例集X開始自舉:
用Go語言編寫Go語言的編譯器,來回測X,直到全部通過。恭喜,從 不舉 變成 自舉 了 ?˙3˙??(??? ? ???)??˙3˙?
詳細可以讀下面的摘要:
&>Google公布實現Go 1.5自舉的計劃
https://studygolang.com/articles/2419
Google最近公布了實現Go 1.5自舉(Bootstrap)的計劃。相關文檔的作者是Go核心開發者Russ
Cox,他在Go語言上已經耕耘了接近6年。據Russ介紹,Google就「如何從Go源碼樹中去除所有的C程序」已經醞釀了一年。自舉(Bootstrapping) 是這樣的過程,「用要編譯的目標編程語言編寫其編譯器(或彙編器)」。一般而言,自舉有幾個優勢,比如:
- 用於測試被自舉的語言;
- 支持使用通常更為高級、提供更多高級抽象的語言來編寫編譯器;
- 編譯器也可以得益於語言層面的任何改進。
如前所述,Google在一年前就開始了從Go源碼樹中去除C代碼的努力,轉換計劃分為5個步驟:
- 第1階段——開發一個從C語言到Go語言的翻譯器,將現有的C編譯器翻譯成Go語言的。這一階段利用了一個事實:原來的編譯器沒有大量使用一些很難移植到Go語言的特性,比如宏、聯合和指針運算等。
- 第2階段——轉換編譯器的源碼樹,得到一個Go語言的編譯器,但是比較原始,而且是C風格的。
- 第3階段——將前面得到的編譯器轉換為符合Go語言習慣的程序,主要通過識別包,添加文檔和單元測試實現。
- 第4階段——優化編譯器,解決編譯器和CPU的內存使用問題,可能引入並行化。此外,嘗試在今天使用的不依賴架構的無序樹(Node*s)和依賴架構的有序列表(Prog*s)之間引入一個新的中間表示,目的是改進編譯器在消除冗餘的nil檢查和邊界檢查等情況下的優化
Go已經實現自舉咯!Go自舉的時候上上下下的Gopher們還高興了好一陣子呢。
可別小瞧自舉,自舉是一門編程語言打通任督二脈、值得得瑟、標榜成熟的特定標誌,要知道有多少編程語言一輩子都實現不了自舉啊~雞生蛋蛋生雞這個比喻用在這裡本身就不太合適,有誤導性。並不是雞生蛋、蛋生雞。好像沒人用Go重新實現C再用這個C來實現Go吧?是蛋生雞,然後雞1.5生雞1.6、雞1.6再生雞1.7 。。。。。。
首先,問題的說法是有問題的。
golang本身是用什麼語言寫的?
從問題描述和下面的回答來看,題主真正想問的是
Golang 的編譯器是用什麼語言寫的?
看起來像是個「雞生蛋,蛋生雞」的問題,實際上不是的。
這個問題的關鍵在於理解,編譯器本身就是一個程序,它的功能就是把源代碼翻譯為計算機可執行的程序。
對於 C/C++、Go、Rust 這樣的本地語言,它們編譯生成後的目標程序就是目標平台的本地可執行程序。比如你用這三種語言寫個 Hello World,在 Windows 平台下用編譯的結果一定是一個 .exe 文件,這些 .exe 文件裡面沒有包含任何源語言的信息。Windows 運行它們的時候不知道,也不需要知道這些 .exe 文件編譯之前是用什麼語言寫的,只需要把它們載入進內存,一句一句地執行指令就行了。
編譯器程序也是這個道理。假如你發明了一種新的語言 CNifeLang,首先需要用一種現有的語言寫一個 CNifeLang 的編譯器,比如說就用 Golang 吧;你用 Golang 寫了一個 CNifeLang 的編譯器,能成功地把任何合法的 CNifeLang 源代碼編譯為等價的目標程序。接著用 CNifeLang 寫一個程序,它與你用 Golang 寫的編譯器功能完全相同,用 Golang 實現的編譯器把這個程序編譯完成,你就得到了一個用 CNifeLang 實現的 CNifeLang 編譯器。因為這個程序的功能與用 Golang 寫的編譯器完全相同,所以你完全可以用這個編譯器去編譯 CNifeLang,於是 CNifeLang 實現了 自舉。
如果題主學習了編譯原理這門課,就會發現編譯與編程語言是沒有關係的,它有一套完整而成熟的操作方法,你完全可以用任何一種圖靈完備的語言去寫任何一種形式語言的編譯器,而且有嚴格的數學方法證明你寫的編譯器是正確的。
我們常見的編程語言基本都實現了自舉,這是一種編程語言發展成熟的標誌之一。因為編譯器既是一個複雜的工程,也有一套成熟的評價體系,能寫出成熟可用、效率有保證的本語言編譯器,就能說明這種語言已經能拿來用了。
最早是C和彙編
最開始是c和彙編,後來go成熟了就用go來重構了
C語言,計算機語言很有意思,有點像是生物進化,是一代一代迭代出來的。
我這裡不拾人牙慧,推薦《深入理解計算機系統》一書閱讀。
先是用C實現的,後來用自己完全實現了所有的代碼。
最早的時候,Golang是用的C和彙編實現的。
後面Golang實現了自舉,重寫了編譯器,所以現在是用的Golang本身實現的。關於這個你查下「自舉」的意思不就就行了么...
不管是Go,還是C++,還是PHP,還是Java,還是等等一切語言的編譯器實現,最初的原型都是語言的開山鼻祖C,Pascal,Fortran,Ada...,其中某些開山鼻祖也是某個鼻祖搞出來的初版,這裡就不深究了.開山鼻祖的語言編譯器基本都是ASM實現.ASM編譯器,或者叫翻譯器/轉換器是用手敲或者打孔機打二進位指令直接實現的.二進位指令和數據狀態讀取都是基於二進位,這是電子電路所能表達的最穩定狀態.而CPU集成了無數的電子電路構成了邏輯電路.電路是由電子的物理現象導致的.而物理現象的定義是神或上帝
所以該問題的終極答案是世界上任何一門語言的編譯器實現是神給出方法,人類通過組合和變換來實現.
推薦閱讀:
※Don"t Learn C the Wrong Way ?
※為什麼很多語言的實現裡面的 Lexer 都沒有使用 DFA?
※基於表驅動實現的詞法分析的一點疑問?
※C/C++語言有哪些不是上下文無關的語法規則?
※應該如何理解「上下文無關文法」?