Go 語言前傳 — 學這能幹嘛?

「即將啟程的旅人啊,汝為何而Go?」

難易度:★★☆☆☆(可能出現一些初學者感到畏懼的專有名詞)

實用度:★★★☆☆(能夠對於Golang的設計有個概括的了解)

Photo by Michał Parzuchowski on Unsplash

【導言】

撰寫本篇文章的目的主要是令讀者知道,為何走上學習Golang(一般簡稱Go)的旅程?而在程式咖啡館小憩一會兒後,阿玉這位新手村的怪路人,能在各位的行囊裡裝些什麼?這些裝備在離開新手村後,又能為將來的挑戰帶來什麼幫助?

【零、開疆闢土】

很久很久以前?冒險故事似乎總得如此開始,然而,Go真的挺年輕,說起Go的誕生,就一定要談談創世紀的Robert Griesemer、Rob Pike和Ken Thompson。

有天,Rob和諸位碼農一樣擼著C++,忽然間,他忿恨不平地噴了句:「X!C++!」(已經過消音處理),這並非一時不滿,而是在經過長年理性的觀察後,Rob對C++累積了滿滿的不悅,包括它語法的複雜性、繁瑣的並行計算等,於是Rob找了志同道合的同事Robert和Ken,三人一同把C++噴個體無完膚,最後,他們決定創造一個新的語言,並定義它必須是:

「能簡潔、可靠、高效率建構軟體的程式語言。」

以下就讓我們深入看看何謂「簡潔、可靠及高效率」吧!

【壹、簡潔】

在Go誕生的2009年,世界上已經有許多簡潔易用的語言,像是隔壁棚的Python,因此Go在設計上,也仿效了這些語言,使Go能更直覺、更優雅。給新手村居民幾個非常簡單的小例子:

告別分號、告別不必要的型別宣告

宣告玉山的海拔,在C++中,我們得這麼打(常會手殘沒寫好):

在 Go的世界,我們只需要:

向醜醜的括號說再見

這是C語言系列中的迴圈、判別式寫法:

而Go呢?能簡單一點點,生產力就能更高一點點!

更多

除此之外,Go在Library的管理、命名規則等也比較嚴謹,令協作的同事們更能容易地讀懂彼此的程式(不得不說,在許多語言中,看別人的Code真的超痛苦!),往後我們將會看到更多Go簡潔、直白的例子。

【貳、可靠】

Go語言誕生於Google,Google是世界數一數二巨型的軟體公司,經常需要建構超大規模的系統,此時就需要使用非常穩定、安全的程式語言,而在經過數十年的考驗後,C++、Java等語言似乎有些致命的缺陷⋯⋯

類別、繼承是一把雙面刃

類別(class)、繼承(inheritance)是什麼呢?以下用Python來做例子:

用Python來實作「水果」

在Object-Oriented語言裡,一切都是Object,為了重複運用一些特性(省去重複打一堆code的麻煩),我們可以「繼承」其性質 ,例如Apple可以繼承Fruit的性質;然而,如果今天這兒的Apple同時也要繼承TechCo(科技公司)呢?雖然仍可實現,但設計上就會變得很棘手,對於其他嘗試看懂這些code的人就更是折磨了(詳見餐後點心)。

於是,Go索性拋棄了class、也拋棄了inheritance,大幅降低團隊開發過程中出錯的機率。另一方面,Go仍提供了能實現Object-Oriented的工具,如下:

用Go來實作「水果」

由於不同於大多數讀者所熟悉的OO語言,具體type、interface和struct等概念究竟是什麼(感謝網柴Jack Shiba補充:Golang和Java的interface不一樣!),稍後我們的旅程中遇到,再詳細做解釋吧~(上茶)

Go由Google維護

就像Java由Oracle維護一樣,Go的開發一樣由Google持續的推動,而且與Java一樣皆是Open Source,每半年會更新一次,如此一來,Go語言能夠持續充滿活力,不容易在程式語言的歷史中稍縱即逝。

更棒的是,Go語言承諾向後兼容,也就是你在老舊版本的Go中寫的Projects,在最新版本中不需做任何修改,即可直接compile使用。反觀,同樣是新興語言、由Apple所維護的Swift,就時常更新內建function的名稱(苦笑)。

更多

另外,Go也具有和Python一樣的Garbage Collection等各種讓系統負擔更小的炫砲功能,之後,在旅途中再慢慢向各位導覽囉。

【參、高效率】

C的後裔,高度像C卻不同於C

電腦運行效率 vs. 程式開發效率、可讀性

Go雖然不像Ruby、Python等語言如此直白,也不像C、C++語言最接近電腦底層。然而,Go一方面借鑑新興語言的簡潔,一方面又略過了如Java的Virtual Machine或是Python的Interpreter等(不一樣的概念歐)中間層的轉譯,能直接將程式碼compile成電腦讀的Binaries,具有相當優越的效能。

平行程式設計(Concurrency)

當實作平行程式設計時⋯⋯

在Go誕生的年代,由於物理上的限制,摩爾定律差不多開始 hold不住了,因此,各大電腦、手機製造商為了追求更高的速度,開始加入多核心的設計。此時,程式語言設計也更加要求平行處理的能力,因為早期的語言尚未遇到這種新興的挑戰,有試過平行程式設計的人都知道,開多執行緒(multithreading)、多行程(multiprocessing)是一件多難的工作。

然而Go可說是一個超級新星,Go內建的Goroutine類似於其他語言的thread,但是更加輕量,同時開數千個Goroutine,也不會佔用太多記憶體空間;另一方面,也相當易懂,例如我們有一個函式f()想要執行:

一般的case
開goroutine的case

是不是很簡單?用goroutine來做平行程式設計竟然只要加上go,真是令百萬名軟體工程師都驚呆了!當然,實作的時候不會總是這麼簡單,不過相較於其他語言,Go可說是具有超前卓越的平行處理能力。

更多

說起Go的高效率,實在是太多能談,也因此近年來,如IPFS、Ethereum、Hyperledger等大型的分布式系統,底層幾乎也都是由Go來實作,許多眼界非凡的先驅都已經使用Go來作為開發系統的語言,你還在等什麼呢?

【結論】

Rob曾說:”Complexity is Multiplicative”(複雜度會彼此相乘而增長的),因此Go的設計高度致力於Simplicity;Go語言誕生是為了實作各類大型系統,在龐大的程式碼中,不能容易出錯、不能缺乏彈性,所以Go也相當Reliable;Go誕生於2009年,借鑒了許多優秀的語言,也同時面對摩爾定律的挑戰,因此Go具有無與倫比的Efficiency

最後,Go最常拿來做什麼呢?引用一句在其他文章中看到的話:

“Go will be the server language of the future.” — Tobias Lütke, Shopify.

恰好能夠回答文章最開頭的問題:

「若汝踏上旅程,是為了建構Server-side system,恭喜,這會是正確的道路!」

本系列文章主要借鑒Go語言聖經《The Go Programming Language》,從新手村到天堂路,整理個人在各種Go的基礎與進階觀念上的筆記,比較不像大補帖式整理或完全的程式新手教學,預計需花費兩年的時間完成這趟旅程,歡迎自學達人們多多關注與指教!

餐後點心

非常感謝網柴(Jack Shiba)幫忙試吃,讓我拙劣的手藝能夠有稍稍進步~以下是今天的餐後點心:

如果你也喜歡我們的文章,幫我們動動手部肌肉,按下掌聲Clap,讓我們有動力繼續煮下一頓料理!

--

--