本文始發於我的公衆號:TechFlow,原創不易,求個關注java
今天是Golang專題的第二篇,咱們來看看Go的語言規範。node
在咱們繼續今天的內容以前,先來回答一個問題。git
有同窗在後臺問我,爲何說Golang更適合分佈式系統的開發?它和Java相比有什麼優點嗎?程序員
其實回答這個問題須要涉及不少概念,好比操做系統當中關於進程、線程、協程等不少概念。咱們將這些內容進行簡化,舉一個最簡單的線程的例子。咱們來寫一段在java當中實現多線程的例子:github
public class MyThread implemnts Runnable {
public void run() {
System.out.println("I am a thread")
}
}
public class Test {
public static void main(String args[]) {
MyThread thread1 = new MyThread();
thread1.start();
}
}
複製代碼
咱們再來看看Golang:golang
func run() {
fmt.Println("I am a Thread")
}
func main() {
go run()
}
複製代碼
這麼一對比是否是簡單不少?web
你們都知道程序員最大的分歧之一就是花括號到底應該寫在哪一行,有另寫一行的,也有跟在循環體後面的。這兩撥人分紅了兩個流派,彼此征戰不休,也衍生出了許多段子。express
爲了統一風格,不少語言對代碼風格作了規範。好比Python就去掉了花括號,而使用空格來進行代碼縮進。然而不幸的是,有些人縮進用四個空格,也有些人用tab,這雙方又造成了陣營,彼此爭吵不停……編程
也許Golang的開發者曾經飽受代碼風格爭吵的苦惱,因此Golang作了一個劃時代的事情,它嚴格限制了代碼風格,強行統一你們都必須使用同一套風格,不然就分分鐘報錯給你看。因此在咱們進行具體的語法學習以前,先從語言規範開始,不然等咱們後面養成了很差的習慣再想要改正就會成本很高。其實改正代碼風格是一件很難的事情,老實說個人代碼風格不是很好,老是使用一些cur、pnt、node、u、v這種簡單的變量,這也是當年打acm留下來的習慣,想改一時半會蠻難的。因此你們必定要在初期就養成好習慣,壞習慣就留給我一我的吧(大霧)。多線程
Golang的語言規範不少,涉及的面很廣,有些咱們暫時用不到,咱們先挑基礎的說。首先是package規範,對於package來講它的名字應該和目錄保持一致,採起有意義的包名,不要起一些別人看不懂的名字。好比test、unit這種,而且不能和標準庫衝突。
其次是咱們在引包的時候,須要注意不要使用相對路徑,而應該使用絕對路徑。
// wrong
import "../../../repo"
// correct
import "github.com/repo/package
複製代碼
固然咱們能夠裝一個goimport工具,幫助咱們自動引包。可是自動引包也會有坑,尤爲是當目錄下存在兩個包名稱同樣的時候,有可能會引入錯誤,須要咱們本身留意。
Go語言當中規定了咱們應該使用駝峯標準來命名變量,不能使用_。在Go當中首字母大寫表示結構體中的變量或者是包中的函數public,若是是小寫則表示是private,這一點尤爲須要注意。剛開始寫go的時候都會很不習慣,所以踩坑是常有的事。
golang當中是有常量的,golang當中的常量同樣用駝峯標準,首字母大寫。好比咱們起一個常量叫作app_env,表示當前app運行的環境,咱們必需要這樣定義:
const AppEnv = "env"
複製代碼
另外一點是Golang的設計者認爲行尾加上分號毫無必要,因此在編譯器當中添加了會在行尾自動加上分號的功能。因此咱們能夠加也能夠不加,可是通常認爲沒有必要這麼作。因此廣泛來講,除了在循環體或者是判斷條件當中,咱們通常是不寫分號的。固然也有特殊狀況,好比你想要把多條語句寫在一行的時候:
var a int; var b float;
a = 3; b = 3.2;
複製代碼
固然仍是通常不推薦這麼幹,建議分紅多行,更加美觀。
另一點是golang當中全部的變量和包都必須用上,不容許定義沒有使用的東西,不然也會報錯。也就是說嚴格限制了咱們寫代碼時候的謹慎。不能隨意申請用不到的變量,大多數語言當中沒有這樣的限制,可是golang當中作了限制,因此咱們寫代碼的時候要當心。
另一點是關於花括號,在golang當中嚴格限制了花括號寫在當前行,而不是另起一行。
// wrong
if expression
{
...
}
// correct
if expression {
...
}
複製代碼
從上面這個例子咱們還能夠注意到一點,就是在golang當中if後面的條件不加括號,這點和Python同樣。可是若是你寫慣了java或者是C++剛開始可能會不太適應。
最後一點是golang的代碼規範檢測工具golint當中規定了全部的函數以及結構體頭部必需要寫註釋,而且對註釋的規範也進行了限制。註釋的規範是名稱加上說明,若是不寫或者是不規範的話,代碼雖然能夠運行,可是沒法經過golint的規範檢測。通常來講公司的開發環境都會作限制,只有經過golint規範檢測的代碼才能夠提交發布。
// HelloWorld print hello world
func HelloWorld() {
fmt.Println("Hello World")
}
複製代碼
另一點是golang不支持隱式類型轉換,好比int和int32以及int64,會被視做是不一樣的類型。若是咱們將一個int32的變量賦值給int類型,則會引發報錯,必需要咱們手動轉換。這固然增長了編碼時候的工做,可是也避免了不少由精度不同產生的問題。
除了這些以外,golang當中還定義了對結構體定義以及錯誤處理等內容的規範。可是對於咱們初學者而言,目前這些是必需要了解的,其餘的內容能夠等咱們後續碰見了再熟悉。
一門語言對於代碼風格作了嚴格的規範限制對於初學者而言多是一件比較蛋疼的事情,由於要記的東西變多了,咱們不只要學會語法,還要搞清楚這些規範。可是當咱們熟悉了或者是工做了以後,會發現這實際上是一件好事。對於多人協做的場景而言,你們都遵照同樣的規範會大大提高代碼交流以及協做的效率。若是大家看過其餘代碼風格和本身徹底不一樣的人的代碼以後,相信大家對於這點必定會有更深的認識。
從規範的嚴格程度以及對面向對象的閹割程度看起來,golang簡直不像是一門新生的語言,倒有些上世紀老派語言的風格。可是恰恰golang又有不少新鮮特性,好比容許函數值返回多個結果,支持匿名函數以及部分函數式編程的功能等等。在初學的階段,我也很是抗拒它,多是由於Python寫得太多了,習慣了動態語言。可是隨着對這門語言瞭解的深刻,我愈來愈多地發現了它這些設計理念背後的思考和智慧,慢慢對它改觀,時至今日,我已經再也不懷疑這是一門優秀的語言,這幾年的流行並非沒有道理的。
另外很重要的一點是,由於golang太特立獨行了,因此常常會讓我思考它這麼作背後的用意是什麼?這麼一思考,加上查閱一些資料,可以發現不少以前思惟當中的盲點。在以前學習語言的時候,我是絕對不會去思考語言的設計者爲何要這麼設計的,只會依葫蘆畫瓢,照着把相關的內容學會僅此而已。這樣的思考除了可以提高對於語言自己的理解以外,也可以提高對問題場景的思考和理解,對於工程師而言,後者實際上是更爲重要的。
固然這些內容我光說是沒有用的,也須要屏幕前的你用心去體會。
但願你們都能感覺到golang的魅力,都能在此過程中收貨成長,加油!若是以爲有所收穫,請順手點個在看或者轉發吧,大家的舉手之勞對我來講很重要。