1. 程式人生 > >Golang——詳解Go語言程式碼規範

Golang——詳解Go語言程式碼規範

本文始發於個人公眾號:TechFlow,原創不易,求個關注


今天是Golang專題的第二篇,我們來看看Go的語言規範。

在我們繼續今天的內容之前,先來回答一個問題。

有同學在後臺問我,為什麼說Golang更適合分散式系統的開發?它和Java相比有什麼優勢嗎?

其實回答這個問題需要涉及很多概念,比如作業系統當中關於程序、執行緒、協程等很多概念。我們將這些內容進行簡化,舉一個最簡單的執行緒的例子。我們來寫一段在java當中實現多執行緒的例子:

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:

func run() {
    fmt.Println("I am a Thread")
}

func main() {
    go run()
}

這麼一對比是不是簡單很多?

Golang的語言規範

大家都知道程式設計師最大的分歧之一就是花括號到底應該寫在哪一行,有另寫一行的,也有跟在迴圈體後面的。這兩撥人分成了兩個流派,彼此征戰不休,也衍生出了許多段子。

為了統一風格,很多語言對程式碼風格做了規範。比如Python就去掉了花括號,而使用空格來進行程式碼縮排。然而不幸的是,有些人縮排用四個空格,也有些人用tab,這雙方又形成了陣營,彼此爭吵不停……

也許Golang的開發者曾經飽受程式碼風格爭吵的苦惱,所以Golang做了一個劃時代的事情,它嚴格限制了程式碼風格,強行統一大家都必須使用同一套風格,否則就分分鐘報錯給你看。所以在我們進行具體的語法學習之前,先從語言規範開始,否則等我們後面養成了不好的習慣再想要改正就會成本很高。其實改正程式碼風格是一件很難的事情,老實說我的程式碼風格不是很好,總是使用一些cur、pnt、node、u、v這種簡單的變數,這也是當年打acm留下來的習慣,想改一時半會蠻難的。所以大家一定要在初期就養成好習慣,壞習慣就留給我一個人吧(大霧)。

package規範

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的魅力,都能在此過程當中收貨成長,加油!如果覺得有所收穫,請順手點個在看或者轉發吧,你們的舉手之勞對我來說很重要。

相關推薦

Golang——Go語言程式碼規範

本文始發於個人公眾號:TechFlow,原創不易,求個關注 今天是Golang專題的第二篇,我們來看看Go的語言規範。 在我們繼續今天的內容之前,先來回答一個問題。 有同學在後臺問我,為什麼說Golang更適合分散式系統的開發?它和Java相比有什麼優勢嗎? 其實回答這個問題需要涉及很多概念,比如作業系統當

Go語言I/O多路複用netpoller模型

> 轉載請宣告出處哦~,本篇文章釋出於luozhiyun的部落格:https://www.luozhiyun.com > > 本文使用的go的原始碼15.7 可以從 Go 原始碼目錄結構和對應程式碼檔案瞭解 Go 在不同平臺下的網路 I/O 模式的實現。比如,在 Linux 系統下基於 epoll,free

Go語言排程迴圈原始碼實現

> 轉載請宣告出處哦~,本篇文章釋出於luozhiyun的部落格: https://www.luozhiyun.com/archives/448 > > 本文使用的go的原始碼15.7 ## 概述 提到"排程",我們首先想到的就是作業系統對程序、執行緒的排程。作業系統排程器會將系統中的多個執行緒按照一定演

微信公眾平臺萬能程式碼-php語言(二)

1.基礎知識在上一篇地址有講解和圖片,內容大致包括微信開發者模式後臺配置、微信公眾開發者文件程式碼詳解。 2.本篇將粘貼出包括所有型別在內的訊息處理辦法,在開發者模式下用程式碼完成所有編輯模式的基礎內容。 3.本篇程式碼是最基礎的微信公眾平臺功能,大家要掌握如何套用。 =

golang defer

什麽是 strong final 例子 拋出異常 包含 over def span 什麽是defer defer用來聲明一個延遲函數,把這個函數放入到一個棧上, 當外部的包含方法return之前,返回參數到調用方法之前調用,也可以說是運行到最外層方法體的"}"時調用。我們

Spring IOC -bean物件的生命週期(補充,含程式碼)

生命週期執行的過程如下:1) spring對bean進行例項化,預設bean是單例2) spring對bean進行依賴注入3) 如果bean實現了BeanNameAware介面,spring將bean的id傳給setBeanName()方法4) 如果bean實現了BeanFactory

深入C++中API的問題_C 語言

前言:本文書寫的格式與其它不相同。本文題目說是關於C++ API的思考,其實也不僅僅是C++,對於其它語言同樣適用。 API實際是指Application Programming Interface,應用程式程式設計介面。對API是一套用來控制Windows的各個部件的外觀和行為的一套預先定義的Window

C語言在字串的指定位置插入字元

問題分析 在字串S的所有數字字元前加一個$字元,可以有兩種實現方法。方法一:用串S拷貝出另一個串T,對串T從頭至尾掃描,對非數字字元原樣寫入串S,對於數字字元先寫一個$符號再寫該數字字元,最後,在S串尾加結束標誌。使用此方法是犧牲空間,贏得時間。方法二:對串S從頭至尾掃描,當遇到數字字元時,從該字元至串

logging模組以及常見程式碼

1.在django中獲取客戶端IP地址: if 'HTTP_X_FORWARDED_FOR' in request.META: ip = request.META['HTTP_X_FORWARDED_FOR'] else: ip = request.META['REMOTE_ADDR']

一文NGram語言模型以及困惑度perplexity

  歡迎關注“勇敢AI”公眾號,更多python學習、資料分析、機器學習、深度學習原創文章與大家分享,還有更多電子資源、教程、資料集下載。勇敢AI,一個專注於人工智慧AI的公眾號。 ==========================================

java類的幾種關係(有程式碼、有類圖)

前言 知道類的幾種關係也是程式設計的基礎知識,通常我們在軟體設計、架構設計、開發中都需要使用的, 類的關係 一般情況下類的關係分為6種,分別是實現、繼承、依賴、關聯、聚合、組合,下面將這6中關係簡單的分類 (1)is a -->繼承、實現 (2)has a-->關聯、

200行go語言程式碼自建一個區塊鏈 體驗挖礦樂趣

談談區塊鏈: 挖礦的目的:通過挖礦證明算力,防止他人作弊,自己又能獲得獎勵【給自己加錢】。 挖礦的過程:將網上別的合法且最新的使用者交易同步過來,加入到區塊,然後加隨機數雜湊後 與系統給出的值去比較。若符合條件則表示挖礦成功,挖礦成功了還不行,要趕緊告訴別人,我挖成功了,別讓其他人搶風

golang第二課---go語言介紹及版本檢視

跨平臺特性 Go語言和Java,Python一樣,也是支援跨平臺的。另外,Go語言還有黑科技:支援跨平臺編譯。比如你手頭只有Mac系統,而你的使用者有Linux和Windows的,他們也想使用你的Go語言程式,你可以通過交叉編譯出Linux和Windows上的可執行

golang基礎學習---Go 語言型別轉換

Go 語言型別轉換 型別轉換用於將一種資料型別的變數轉換為另外一種型別的變數。Go 語言型別轉換基本格式如下: type_name(expression) type_name 為型別,expression 為表示式。 例項 以下例項中將整型轉化為浮點型,並計算結果,將結果賦

golang基礎學習----Go 語言陣列

陣列定義 陣列是具有相同唯一型別的一組已編號且長度固定的資料項序列(這是一種同構的資料結構);這種型別可以是任意的原始型別例如整形、字串或者自定義型別。陣列長度必須是一個常量表達式,並且必須是一個非負整數。需要強調:陣列長度也是陣列型別的一部分。 Go語言陣列 陣列是Go語言程式設

golang基礎學習---Go 語言變數作用域

Go 語言變數作用域 作用域為已宣告識別符號所表示的常量、型別、變數、函式或包在原始碼中的作用範圍。 Go 語言中變數可以在三個地方宣告: 函式內定義的變數稱為區域性變數 函式外定義的變數稱為全域性變數 函式定義中的變數稱為形式引數 接下來讓我們具體瞭解區域性變數、全域性變

golang基礎學習---Go 語言 break 語句和continue語句

Go 語言 break 語句 Go 語言中 break 語句用於以下兩方面: 用於迴圈語句中跳出迴圈,並開始執行迴圈之後的語句。 break在switch(開關語句)中在執行一條case後跳出語句的作用。 示例 package main import "fmt" fu

golang基礎學習----go語言控制語句switch

Go 語言 switch 語句 switch 語句用於基於不同條件執行不同動作,每一個 case 分支都是唯一的,從上直下逐一測試,直到匹配為止。。 switch 語句執行的過程從上至下,直到找到匹配項,匹配項後面也不需要再加break 基本結構 相比較 C 和 Jav

OpenCV中copyTo()函式及Mask(附程式碼

copyTo函式有兩種重構方式: 第一種:A.copyTo(B),表示將A矩陣複製到B中 第二種:A.copyTo(B, mask),表示得到一個附加掩膜mask的矩陣B。 第一種方法就不多贅述,這裡主要詳細敘述第二種使用方法。  對於第二種mask引數的格

C語言程式碼規範(程式設計規範

C語言程式碼規範(程式設計規範) 什麼叫規範?在C語言中不遵守編譯器的規定,編譯器在編譯時就會報錯,這個規定叫作規則。但是有一種規定,它是一種人為的、約定成俗的,即使不按照那種規定也不會出錯,這種規定就叫作規範。 雖然我們不按照規範也不會出錯,但是那樣程式碼寫得就會很亂。大家剛開始學習C語言