從10年以來,我一直在專業地使用PHP進行編程。在獲得計算機工程學位後,我所知道的就是Java不再是我的小菜了(在個人和學術項目中使用Java 6年以上),我想要很多更簡單的堆棧,我發現作為獨立開發人員推銷自己的一種快速方法是進入不斷增長的PHP CMS市場。
多年來,PHP發生了變化很多儘管許多人喜歡抨擊或批評它,但許多人是基於非常古老且很少的經驗來這樣做的。現代PHP(特別是如果您願意使用PHP 7類型並拋棄PHP 5.x)非常好用,當然,由於某些原因,PHP的優勢在於幾乎可以部署該語言到處都是,這就是為什麼許多CMS是用PHP內置的,以及為什麼如此成功的原因因為它們是基於PHP的(重力包括)。
當然,PHP只是一個工具,最近我一直在深入研究Go。
與PHP相比,Go是一種完全不同的語言和環境。
這不是旨在使您脫離PHP的喧囂或文章,而是向您介紹PHP開發人員,為什麼Go是一種很好的語言,可以作為一種輔助工具來學習。
首先,什麼是Go?
Go是10年前由Google設計的命令式,面向對象的編程語言。
創始成員的綜合知識以及為滿足他們的需求而創建最佳語言的原始哲學促成了Go。
Go是一種靜態類型的編譯語言,具有內置的垃圾回收和並發編程功能。
沒什麼新鮮的
Go進行創新的方式非常有趣。它完全忽略了關於現代語言應該具有的新功能以及其他編程語言所提供的功能的炒作,而是取而代之的是從經過考驗的語言中挑剔的核心概念,將數十年的編程經驗匯總為一個漂亮的工具來使用。
The task of the programming language designer is consolidation not innovation – Hoare, 1973
Go具有許多獨特的功能,當然,它不僅僅是一種mashup語言。去介紹例行程序,這是處理並發的絕佳方法。去介紹推遲,這是在外部函數返回時執行某些操作的好方法(現在也已添加到Swift中)。
Go是在標準工具中引入格式化程序的第一種語言。並能夠在沒有摩擦的情況下為其他平台進行編譯的能力,以及更多的“新”事物。
Go紮根。羅伯特·格里斯麥默(Robert Griesemer)在GopherCon 2015上的精彩演講說明了這一點:Go融合了兩者的許多原理C和Oberon-2,這是一種來自Pascal家族的語言。這兩種語言都起源於1960年推出的Algol 60。
所以下一次有人問為什麼Go看起來像20年前的語言,您也可以回答它實際上擁有60多年的經驗。正如Robert Griesemer曾經說過的那樣,一種編程語言成為主流需要10年的時間。
Go才剛剛起步,這對它的未來以及人們可以用它構建什麼感到非常激動!
Go是PHP的補充
如果您除了PHP之外還使用Ruby或Python,您可能已經意識到,如果您從方程式中刪除了狂熱主義和個人喜好,因為它們都是解釋性的,鬆散類型的語言,那麼它們或多或少可以歸結為PHP的不同版本。
可以將Ruby轉換為PHP和Python,然後做同樣的事情。唯一有很大不同的“網絡語言”是JavaScript,這是由於非阻塞模型(但已通過庫遷移到其他語言,包括PHP和非阻塞模型)並且因為它是當前在瀏覽器中本機運行的唯一語言而有所不同,這給它帶來了巨大的優勢。而且,它是一個不受控制的執行環境,更加狂野的生態系統,所有這些都可能以微妙的方式有所不同。
另一方面,這是完全不同的野獸。它是一種系統語言,例如C。與動態語言不同,Go的運行速度很快。
PHP是用C內置的,您可以編寫和運行PHPC擴展,因此系統語言的概念不應那對你來說陌生。
Go能夠替換您的Web堆棧,並且可以使用它來簡化Web框架,但是PHP仍然佔有一席之地,特別是在進行原型設計時,您仍然不知道代碼的哪一部分需要大量優化,並且畢竟您的代碼是否真的會被使用。
那麼,什麼時候應該使用Go?當您使用PHP時,PHP並不是真正的最佳工具。如果PHP為某項特定功能佔用了過多的內存或資源,則高度優化的Go程序的性能會更好。就那麼簡單。 PHP 7在改善PHP性能方面令人讚嘆。那是免費的禮物。但是,當您需要處理數百萬個數據庫條目,或者需要長時間運行從API獲取千兆字節的數據時,PHP可能不是正確的工具。
我依靠Node.js解決這個問題已經有很多年了,但是據我所知,Go到目前為止,我提出的任何東西都是一個更簡單,更好的解決方案。
當然,它並不止於此。使用Go,您可以輕鬆地構建跨平台的並發應用程序,這與PHP Web開發有很大的不同,方法更具挑戰性,但就個人而言,也更有趣,它可以為您帶來許多有意義的工作。
因此,作為PHP開發人員,您可以開始將艱鉅的任務交到Go手中,同時熟練掌握它肯定會豐富您的職業選擇。
為什麼選擇Go,而不選擇C C ++或Java?
任何語言都有它的位置。當然,Go不能擊敗C和C ++的性能。您可以找到許多基準。
Go介於這兩種主流語言和歷史性語言以及動態語言之間:您想要的性能要比解釋語言所能提供的更多,但是您還不准備或不願意使用C或C ++,它們速度更快,但是它們級別太低,您需要手動管理內存,這將花費更多的時間來開發。去適合那個地方。
對於經過高度優化的代碼,如果您精通C或C ++,則它們可能是更好的解決方案。我可以對大會說同樣的話。
與Java相比,情況完全不同。 Java在環境方面需要大量的開銷,而Go程序是單個文件,輕巧,可移植並且是本機的。
而且我們可能正在將蘋果與橘子進行比較,您永遠不會在使用Java的地方使用Go,而事實恰恰相反。
內心很簡單
(並且要記住:簡單並不意味著容易)避免功能蠕變顯然是Go設計師的目標之一。傳奇人物肯·湯普森(Ken Thompson)是Go的三位原創設計師之一,也是UNIX和B語言的創造者(還有許多其他事情),他曾經說過
當我們三個人(湯普森,羅伯·派克和羅伯特·格里塞梅爾)開始時,這純粹是研究。我們三個在一起,決定討厭C ++。 [笑聲]…[回到Go,]我們開始的想法是,我們三個人都必須與語言的每個功能進行交談,因此,由於任何原因,都不會在語言中添加任何多餘的垃圾。
對於任何使用任何語言進行編碼的經驗豐富的開發人員來說,這都導致了一種極其簡單的語言。
Java,C ++,C,C#,Erlang,JavaScript,Swift,幾乎所有現代編程語言都比Go更複雜。
在這裡,我的意思是為程序員使用複雜的語言,為閱讀而復雜的語言,為成為一名熟練者而復雜的語言。在內部,Go隱藏了所有復雜性並公開了一個簡單的API。 Go不僅具有垃圾回收功能,而且根本沒有公開的內存管理功能。
試想一下,PHP有67個關鍵字,而Go有25個關鍵字。
這裡的關鍵是我們的程序員是Google員工,而不是研究人員。他們通常相當年輕,剛從學校畢業,可能學習過Java,也許學習過C或C ++,可能學習過Python。他們無法理解出色的語言,但我們希望使用它們來構建優秀的軟件。因此,我們提供給他們的語言必須易於理解和採用。 —羅伯·派克
這是Go語言哲學的核心,並解釋了為什麼Go選擇避免實現特徵(避免特徵爬升),以及為什麼函數編程的許多概念因其複雜性而被排除在外而引發了爭論。純粹的函數式編程與機器概念相距太遠,無法與Go相關,Go是一種核心命令語言。
也就是說,Go實現了許多功能編程的概念,例如一流的函數(允許將函數分配給變量),閉包,遞歸。
但是與PHP或JS相比,您沒有諸如map,reduce或filter之類的功能性操作,必須依靠循環。為什麼?因為這些操作效率低下,所以Go必須找到一個平衡點。
說到缺少的東西,沒有例外可以處理錯誤。沒有類(即使它是面向對象的,具有帶關聯方法的結構,強制超越繼承的組成—如果您了解JavaScript的原型對象實現的知識,那將是熟悉的,但有很大的不同),不需要泛型(儘管PHP也沒有泛型),以及這就是為什麼。
好的軟件設計的“秘密”不是在知道要在代碼中添加什麼。那是在知道剩下什麼!這是在識別硬點和軟點在哪裡,並且知道在哪裡留出空間/房間,而不是試圖在更多設計中塞滿東西。
只有一種編寫循環的方法:for
。忘記while
和do — while
和foreach
(還有嗎?)。
從函數返回多個值的能力避免了很多麻煩(最簡單的示例是返回包含2個值的數組,並且必須在不知道傳遞的確切類型的情況下提取它們)。
工具繼承了簡單性。gofix自動修復新的Go版本中突破性的API更改。
Go在設計上很簡單,並且將始終保持簡單。
正如羅伯·派克(Rob Pike)所說,許多其他語言正在互相複製功能,從而失去了它們獨特的方面(例如,JavaScript引入了類語法來取悅Java和PHP開發人員),並且它們在理想情況下都融合到了概念上獨特的語言。
Go不能在功能上競爭。這讓我想起這篇越來越真實的文章。
當心:圍棋是兩極分化的
Go有很多粉絲,也有很多仇恨者。作為一名PHP開發人員,我敢肯定您在這種火焰大戰中發展出了厚厚的皮膚,我們可以迅速進行下一步。它非常受歡迎,並且開發人員有很強的見解。
Go很好地解決了問題。而且您不必成為天才就可以開始使用它,儘管這可能會損害您的感覺。
Go非常自以為是,有明確的約定
您會發現關於Go的第一件事就是幾乎所有可以找到的代碼都幾乎相同。
這是因為Go具有明確和強制的約定。內置工具提供了2條與約定有關的命令(gofmt和lin,其中包含第一個自動格式化代碼,第二個僅顯示警告),他們可以檢查您的代碼是否符合要求,甚至可以根據Go準則自動調整樣式。
這與JS不同ESLint/ JSHint,因為這些工具是團隊範圍的應用程序。就像在所有JS中一樣,您可以自定義首選項中的任何內容。gofmt
是一種,沒有配置,這就是要遵循的風格。
這對於在您自己的代碼上提供一致性非常有用(您5年前用PHP或JavaScript編寫的代碼可能是非常與您當前的約定和首選項不同)和代碼每個人分發。
想像沒有更多的內部團隊討論最佳的代碼樣式,想像一下開源項目中所有PR都以相同的方式進行格式化和刪除。分隔vs0選項卡,節省思維周期-它是選項卡。大括號是在同一行還是在下一行?總是同一行(這是有原因的,它允許省略分號)。
如果未使用變量或導入,Go會引發編譯錯誤,從而防止程序隨時間累積垃圾。
命名約定是如此重要,以至於訪問修飾符已從等式中完全刪除。小寫變量?私人的。大寫變量?上市。如此簡單,一個簡單的約定就消除了大量無用的屏幕空間使用,並且立即可以理解。
註釋有特殊需要,您可以使用特殊語法編寫註釋,以便可以使用以下命令檢查軟件包go doc
並且您擁有所需的所有文檔,而無需在Google上進行搜索。
go get
內置的(可用於開源和發行版)供您使用。雖然在我看來,PHPland在依賴項管理方面要先進得多。
PHPUnit /代碼接收?不需要,go test
已經為您服務*_test.go
文件。
它使您成為更好的程序員
如果您來自PHP,那麼學習Go會讓您以另一種全新的方式思考。這將使您成為更好的程序員,就像學習任何其他語言一樣:它向您介紹了新概念。如果感覺陌生而陌生,則說明您正在學習並成長為一名開發人員是一個好兆頭。
首先,Go是編譯而不是解釋的。完全不同的工作流程和部署。
如果您沒有使用強類型的經驗,那將是一個範式更改。 PHP 7附帶了類型檢查功能,如果您不必支持舊版本的PHP,它會提供很大的幫助。 Go是強類型的。許多(如果不是全部)類型問題在編譯時已解決。
Go非常簡單,設計得很簡單,而成為Go開發人員意味著要認識到這種簡單性並加以利用,而不是嘗試編寫類似於Java的Go,而是要接受它。
簡單地說,我並不是說Go是一種玩具語言,它當然不是,而且我也不是要向某人介紹編碼的語言。
簡單來說,我的意思是更多極簡主義和無絨毛。
當一種語言為您提供多種方法來做相同的事情時,您就不得不思考哪種才是最好的,這會分散您要解決的問題的注意力。
您可以從PHP運行Go代碼
因此,我建議一開始的一種方法是編寫一些繁重的例程或長時間運行的代碼,這些代碼作為Go服務會佔用過多的內存。
那裡是 許多 方法直接從PHP調用Go程序,但您也可以選擇實現一個通過ZeroMQ的服務隊列,或通過反向代理公開API端點來訪問長期運行的go程序。您有很多選擇。
Go的特殊武器:並發
眾所周知,PHP-FPM可以很好地處理並發請求,產生了一個新進程,該進程為每個用戶執行實際的PHP代碼。通常,在Web應用程序中,數據庫是瓶頸。但是,對於長時間運行的進程(您實際上並不想在PHP中構建的東西),或者當您需要在PHP請求中啟動繁重的計算循環(您需要在其中運行成千上萬個並發進程)呢?
PHP具有線程支持,因此它可以執行並發處理,但是雖然PHP(甚至C和其他語言)可以使用語言外部的庫進行並發,但是Go是設計的具有內置的並發編程,並提供了goroutine之間進行通信的本機方式。
線程比較重例行程序。一個系統可以支持10k線程,而同一系統可以支持數百萬個goroutine,因為內部實現了goroutine的內存消耗要輕得多,例如Java或Erlang。
因此,即使您不需要數百萬個並發請求,性能提升也很明顯。
此外,通過簡單的方式消化goroutine並了解代碼的作用非常容易。
無需擴展類或包括特殊擴展名,這些擴展名可能並不總是可用(這有效地限制了我們可以將PHP並髮用於自行安裝的分佈式代碼的程度)
只需輸入go someFunction()
該函數將在goroutine中執行。
結論
如果您是Go的新手PHP開發人員,希望您現在對這個工具感到好奇,並考慮該工具在什麼地方有用,或者是否適合您。
如果您是一個喜歡簡單而不是複雜,而是喜歡直接和可讀的代碼而不是抽象的程序員,那麼我相信您會發現Go真的很有趣。
更多教程:
- 使用NGINX反向代理服務Go服務
- 在Go中復制結構
- Go Web服務器的基礎
- 在Go中對地圖類型進行排序
- 簡而言之去指針
- 轉到標籤說明
- 開始日期和時間格式
- 使用Go進行JSON處理
- 可變參數函數
- 去弦備忘單
- 轉到空界面說明
- 使用VS Code和Delve調試Go
- 命名為Go返回參數
- 在Go中生成隨機數和字符串
- Go項目的文件系統結構
- Go中的二進制搜索算法
- 在Go中使用命令行標誌
- GOPATH解釋
- 使用Go構建一個命令行應用程序:lolcat
- 使用Go構建CLI命令:Cowsay
- 在Go中使用殼管
- Go CLI教程:財富克隆
- 使用Go列出文件夾中的文件
- 使用Go從GitHub獲取存儲庫列表
- 去,將一小段字符串附加到文件中
- 去,將字符串轉換為字節片
- 使用Go可視化您本地的Git貢獻
- Go CPU和內存分析入門
- 解決Go程序中的“不支持索引”錯誤
- 測量Go程序中的執行時間
- 使用Go構建Web爬網程序以檢測重複的標題
- 最佳實踐:指針還是價值接收者?
- 最佳實踐:您應該使用方法還是函數?
- Go數據結構:集
- 前往地圖備忘單
- 在Go中生成泛型類型的實現
- Go數據結構:字典
- Go數據結構:哈希表
- 在“通過通道”中實現事件偵聽器
- Go數據結構:堆棧
- Go數據結構:隊列
- Go數據結構:二進制搜索樹
- Go數據結構:圖形
- Go數據結構:鍊錶
- Go數據結構的完整指南
- 比較Go值
- Go是面向對象的嗎?
- 在Go中使用SQL數據庫
- 在Go中使用環境變量
- 上篇教程:PostgreSQL支持的REST API
- 在Go Web服務器上啟用CORS
- 在Docker容器中部署Go應用程序
- 為什麼Go是作為PHP開發人員學習的功能強大的語言
- 去,刪除io.Reader.ReadString換行符
- 開始,如何觀看更改並重建程序
- 去算一下自約會以來的月份
- 在Go中訪問HTTP POST參數