溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

go fmt命令有什么用

發(fā)布時(shí)間:2023-01-31 09:23:33 來(lái)源:億速云 閱讀:98 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“go fmt命令有什么用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

在go語(yǔ)言中,“go fmt”命令主要是用來(lái)幫開(kāi)發(fā)者格式化所寫(xiě)好的代碼文件?!癵o fmt”命令會(huì)按照Go語(yǔ)言代碼規(guī)范格式化指定代碼包中的所有Go語(yǔ)言源碼文件的代碼,所有Go語(yǔ)言源碼文件即包括命令源碼文件、庫(kù)源碼文件和測(cè)試源碼文件?!癵o fmt”命令只會(huì)格式化被直接保存在指定代碼包對(duì)應(yīng)目錄下的Go語(yǔ)言源碼文件。

go fmt命令介紹

對(duì)于一門(mén)編程語(yǔ)言來(lái)說(shuō),代碼格式化是最容易引起爭(zhēng)議的一個(gè)問(wèn)題,不同的開(kāi)發(fā)者可能會(huì)有不同的編碼風(fēng)格和習(xí)慣,但是如果所有開(kāi)發(fā)者都能使用同一種格式來(lái)編寫(xiě)代碼,那么開(kāi)發(fā)者就可以將主要精力放在語(yǔ)言要解決的問(wèn)題上,從而節(jié)省開(kāi)發(fā)時(shí)間。

Go語(yǔ)言的開(kāi)發(fā)團(tuán)隊(duì)制定了統(tǒng)一的官方代碼風(fēng)格,并且推出了 gofmt 工具(gofmt 或 go fmt)來(lái)幫助開(kāi)發(fā)者格式化他們的代碼到統(tǒng)一的風(fēng)格。

gofmt 是一個(gè) cli 程序,會(huì)優(yōu)先讀取標(biāo)準(zhǔn)輸入,如果傳入了文件路徑的話,會(huì)格式化這個(gè)文件,如果傳入一個(gè)目錄,會(huì)格式化目錄中所有 .go 文件,如果不傳參數(shù),會(huì)格式化當(dāng)前目錄下的所有 .go 文件。

而Go語(yǔ)言中還有一個(gè)go fmt命令,go fmt命令是 gofmt 的簡(jiǎn)單封裝。

go fmt命令有什么用

go fmt命令主要是用來(lái)幫你格式化所寫(xiě)好的代碼文件【很多第三方集成軟件都是使用了go fmt命令】

使用:

go fmt <文件名>.go

使用go fmt命令,更多時(shí)候是用gofmt,而且需要參數(shù)-w,否則格式化結(jié)果不會(huì)寫(xiě)入文件。gofmt -w src,可以格式化整個(gè)項(xiàng)目。

參數(shù)介紹

  • -l 顯示那些需要格式化的文件

  • -w 把改寫(xiě)后的內(nèi)容直接寫(xiě)入到文件中,而不是作為結(jié)果打印到標(biāo)準(zhǔn)輸出。

  • -r 添加形如“a[b:len(a)] -> a[b:]”的重寫(xiě)規(guī)則,方便我們做批量替換

  • -s 簡(jiǎn)化文件中的代碼

  • -d 顯示格式化前后的diff而不是寫(xiě)入文件,默認(rèn)是false

  • -e 打印所有的語(yǔ)法錯(cuò)誤到標(biāo)準(zhǔn)輸出。如果不使用此標(biāo)記,則只會(huì)打印不同行的前10個(gè)錯(cuò)誤。

  • -cpuprofile 支持調(diào)試模式,寫(xiě)入相應(yīng)的cpufile到指定的文件 作用區(qū)域

go fmt與gofmt

go fmt命令會(huì)按照Go語(yǔ)言代碼規(guī)范格式化指定代碼包中的所有Go語(yǔ)言源碼文件的代碼,所有Go語(yǔ)言源碼文件即包括命令源碼文件、庫(kù)源碼文件和測(cè)試源碼文件。注意,當(dāng)代碼包還有子代碼包時(shí),子代碼包中的Go語(yǔ)言源碼文件是不包含在內(nèi)的。也就是說(shuō),go fmt命令只會(huì)格式化被直接保存在指定代碼包對(duì)應(yīng)目錄下的Go語(yǔ)言源碼文件。

與go doc命令和godoc命令的關(guān)系類(lèi)似,go fmt命令是gofmt命令的簡(jiǎn)單封裝。go fmt命令本身可以接受兩個(gè)標(biāo)記。標(biāo)記-n可以讓命令程序僅打印出內(nèi)部使用的gofmt命令及其標(biāo)記和參數(shù)而不真正執(zhí)行它。標(biāo)記-x則會(huì)使命令程序既打印又執(zhí)行這個(gè)命令。在go fmt命令程序內(nèi)部,會(huì)在其調(diào)用的gofmt命令后面加上標(biāo)記-l和-w,并以指定代碼包中的所有Go語(yǔ)言源碼文件的路徑作為參數(shù),就像這樣:

hc@ubt:~$ go fmt -n pkgtool
gofmt -l -w golang/goc2p/src/pkgtool/envir.go golang/goc2p/src pkgtoolenvir_test.go golang/goc2p/src/pkgtool/fpath.go golang/goc2p/src/pkgtool ipath.go golang/goc2p/src/pkgtool/pnode.go golang/goc2p/src/pkgtool/util.go golang/goc2p/src/pkgtool/util_test.go

注意,作為gofmt命令參數(shù)的Go語(yǔ)言源碼文件的路徑是相對(duì)的,而不是絕對(duì)的。不過(guò)這只是為了讓參數(shù)看起來(lái)更短一些而已。所以,當(dāng)我們直接執(zhí)行g(shù)ofmt命令的時(shí)候,使用源碼文件的絕對(duì)路徑作為參數(shù)也是沒(méi)有問(wèn)題的。實(shí)際上,任何Go源碼文件或包含有Go語(yǔ)言源碼文件的目錄的相對(duì)路徑或絕對(duì)路徑都可以作為gofmt命令的參數(shù)。當(dāng)使用包含有Go語(yǔ)言源碼文件的目錄的絕對(duì)路徑或相對(duì)路徑作為參數(shù)時(shí),gofmt命令會(huì)把在這個(gè)目錄下的Go語(yǔ)言源碼文件作為目標(biāo)源碼文件。

go fmt命令程序內(nèi)部在執(zhí)行g(shù)ofmt命令時(shí)加入的標(biāo)記是固定的。如果我們想使用與之不同的標(biāo)記集合就必須直接使用gofmt命令了?,F(xiàn)在我們來(lái)看一下gofmt命令可接受的所有標(biāo)記。如下表。

表0-13 gofmt命令的標(biāo)記說(shuō)明

標(biāo)記名稱標(biāo)記描述
-cpuprofile把CPU概要寫(xiě)入指定文件。文件的路徑應(yīng)該作為此標(biāo)記的值。
-d顯示格式化前后的不同(如果有的話),而不是直接格式化那些代碼。
-e報(bào)告目標(biāo)源碼文件中的所有錯(cuò)誤。默認(rèn)情況下,僅會(huì)顯示前10個(gè)錯(cuò)誤。
-l僅把那些不符合格式化規(guī)范的、需要被命令程序改寫(xiě)的源碼文件的絕對(duì)路徑打印到標(biāo)準(zhǔn)輸出。而不是把改寫(xiě)后的全部?jī)?nèi)容都打印到標(biāo)準(zhǔn)輸出。
-r添加形如“a[b:len(a)] -> a[b:]”的重寫(xiě)規(guī)則。如果我們需要自定義某些額外的格式化規(guī)則,就需要用到它。規(guī)則字符串應(yīng)該作為此標(biāo)記的值。
-s簡(jiǎn)化文件中的代碼。
-w把改寫(xiě)后的內(nèi)容直接寫(xiě)入到文件中,而不是作為結(jié)果打印到標(biāo)準(zhǔn)輸出。

看過(guò)上表中的信息,我們就很容易理解go fmt命令的行為了。因?yàn)樗趦?nèi)部執(zhí)行了gofmt命令,并加入了標(biāo)記-l和-w。這會(huì)使命令程序打印需要改寫(xiě)的文件的絕對(duì)路徑到標(biāo)準(zhǔn)輸出,并且直接把格式化后的內(nèi)容寫(xiě)入到原始文件中。在默認(rèn)情況下,gofmt命令會(huì)把格式化后的內(nèi)容直接打印到標(biāo)準(zhǔn)輸出上。

實(shí)際上,命令程序會(huì)把目標(biāo)源碼文件中的內(nèi)容解析成抽象語(yǔ)法樹(shù)。當(dāng)在解析過(guò)程中發(fā)現(xiàn)語(yǔ)法錯(cuò)誤時(shí),命令程序就會(huì)顯示錯(cuò)誤提示信息并退出。在默認(rèn)情況下,目標(biāo)源碼文件中的語(yǔ)法錯(cuò)誤不會(huì)全部被顯示出來(lái)。我們可以加入標(biāo)記-e以使命令程序打印出全部錯(cuò)誤到標(biāo)準(zhǔn)輸出。

自定義改寫(xiě)操作

在默認(rèn)情況下,gofmt命令對(duì)Go語(yǔ)言源碼文件的改寫(xiě)操作包括如下幾個(gè)方面:

  • 以字典序排序依賴包導(dǎo)入語(yǔ)句塊中代碼包導(dǎo)入路徑的先后順序。

  • 標(biāo)準(zhǔn)化各個(gè)語(yǔ)言或語(yǔ)句塊之間的縮進(jìn)、空格和換行。比如,把所有的\r\n轉(zhuǎn)換成\n。

  • 對(duì)代碼語(yǔ)法的小修正。比如,消除用于判斷變量類(lèi)型的switch語(yǔ)句塊中多余的圓括號(hào)。

如果想自定義額外的改寫(xiě)操作,需要使用-r標(biāo)記。-r標(biāo)記的值中必須包含“->”,比如a[b:len(a)] -> a[b:]?!?>”的左邊應(yīng)該是需要被替代的表達(dá)式的示例,而右邊則應(yīng)該是用來(lái)替代“->”左邊表達(dá)式的表達(dá)式的示例。

如果我們使用標(biāo)記-r,那么命令程序在解析源碼文件之前會(huì)將此標(biāo)記值中的被替換表達(dá)式和替換表達(dá)式分別解析為抽象語(yǔ)法樹(shù)的表達(dá)式節(jié)點(diǎn)。如果解析不成功,也就意味著無(wú)法進(jìn)行后續(xù)的替換操作,命令程序會(huì)在打印錯(cuò)誤提示信息后退出。如果解析成功,那么命令程序會(huì)在解析源碼文件成功之后進(jìn)行表達(dá)式替換操作。命令程序會(huì)尋找該源碼文件的抽象語(yǔ)法樹(shù)中與被替換表達(dá)式相匹配的節(jié)點(diǎn),并用替換表達(dá)式替換之。gofmt命令已支持但不限于如下自定義替換操作:

  • 程序?qū)嶓w名稱的替換。程序?qū)嶓w包括變量、常量、函數(shù)、結(jié)構(gòu)體和接口。比如:-r=array1->array2和-r=FuncA->FuncB。

  • 程序?qū)嶓w類(lèi)型的替換,其中也包含函數(shù)的參數(shù)和結(jié)果的類(lèi)型的替換。比如:-r=string->bool和-r=interface{}->int。

  • 多余圓括號(hào)的清除。比如:我們這樣設(shè)置標(biāo)記-r=(x)->x會(huì)使目標(biāo)代碼中的a = (-x.s)被改寫(xiě)為a = -x.s,也會(huì)使代碼中的((b = -x.f()))被改寫(xiě)為b = -x.f(),還會(huì)使c = -(x).f改寫(xiě)為c = -x.f,但是不會(huì)去掉d = (&x).s和e = (-x).f()中的圓括號(hào)。也就是說(shuō),命令程序會(huì)在不改變語(yǔ)義和不產(chǎn)生語(yǔ)法歧義的前提下清除代碼中多余的圓括號(hào)。

  • 數(shù)值操作的替換。比如:我們這樣設(shè)置標(biāo)記-r=x+x->x*2會(huì)使代目標(biāo)碼中的所有的x + x被替換為x * 2。并且,如果需要被替換的表達(dá)式中包含注釋的話,則在替換操作的過(guò)程中會(huì)去掉這些注釋。比如,在同樣的標(biāo)記設(shè)置的情況下x /* It's comment */ + x仍然會(huì)被替換為x * 2。

  • 基于參數(shù)列表的函數(shù)調(diào)用替換。比如:如果我們這樣設(shè)置標(biāo)記-r='funcA(a)->FuncA(a, c)',則目標(biāo)代碼中調(diào)用函數(shù)funcA并以一個(gè)變量作為參數(shù)的語(yǔ)句都會(huì)被替換為調(diào)用函數(shù)FuncA并以變量a和變量c作為參數(shù)的語(yǔ)句。注意,被替換表達(dá)式中作為參數(shù)的a只是表明函數(shù)funcA有一個(gè)參數(shù),而并不關(guān)心這個(gè)參數(shù)的名稱是什么。也就是說(shuō),在同樣的標(biāo)記設(shè)置的情況下,目標(biāo)代碼中的funcA(b)或funcA(x)都會(huì)被替換為FuncA(a, c)。再或者,如果我們這樣設(shè)置標(biāo)記-r='funB(x...)->FunC(x)',則目標(biāo)代碼中的funB(x...)或funB(y...)或其它類(lèi)似的調(diào)用函數(shù)都會(huì)被替換為FunC(x)。其中,當(dāng)類(lèi)型為數(shù)組/切片的參數(shù)后跟三個(gè)英文半角句號(hào)“…”時(shí),則表明需要把這個(gè)參數(shù)中的每一個(gè)元素都作為單獨(dú)的參數(shù)傳入到函數(shù)中。因此,這種替換方式可以用來(lái)在函數(shù)名稱和/或參數(shù)列表改變之后,批量的跟進(jìn)修正調(diào)用該函數(shù)的代碼。

代碼簡(jiǎn)化操作

當(dāng)我們?cè)趫?zhí)行g(shù)ofmt命令時(shí)加入了標(biāo)記-s,命令程序會(huì)在目標(biāo)源碼文件中尋找可以簡(jiǎn)化的代碼并簡(jiǎn)化它。簡(jiǎn)化操作包括:

  • 消除在數(shù)組/切片初始化中的不必要的類(lèi)型聲明。

  • 消除在字典初始化中的不必要的類(lèi)型聲明。

  • 消除在數(shù)組/切片切片操作時(shí)不必要的索引指定。

  • 消除迭代時(shí)的非必要臨時(shí)變量賦值操作。

這些操作基本上都是出于盡量使用Go語(yǔ)言的語(yǔ)法糖已達(dá)到減少代碼量的目的。我們?cè)诰帉?xiě)Go語(yǔ)言代碼的時(shí)候應(yīng)該直接使用這些語(yǔ)法糖而不應(yīng)該依賴使用gofmt命令來(lái)簡(jiǎn)化。這里所說(shuō)的Go語(yǔ)言的語(yǔ)法糖,我們?cè)诘?章中已經(jīng)有所介紹。

我們?cè)诒拘」?jié)中詳細(xì)介紹了go fmt命令和gofmt命令。下面我們?cè)賲R總一下這兩個(gè)命令可以為我們做的事情。如下表。

表0-14 go fmt命令和gofmt命令的功能

功能go fmt命令gofmt命令
格式化代碼
列出不規(guī)范的源碼文件
自動(dòng)改寫(xiě)源碼文件
顯示對(duì)比信息×
提示全部錯(cuò)誤×
簡(jiǎn)化代碼×
自定義替換/重構(gòu)輔助×
CPU概要記錄×

最后,值得一提的是,當(dāng)我們執(zhí)行g(shù)ofmt命令且沒(méi)有加任何參數(shù)的時(shí)候,該命令將會(huì)進(jìn)入到交互模式。在這種模式下,我們可以直接在命令行界面中輸入源碼,并以Ctrl-d結(jié)束。在Linux操作系統(tǒng)下,Ctrl-d代表EOF(End Of File,中文譯為文件結(jié)束符)。需要注意的是,如果在一行的中間按下Ctrl-d,則表示輸出“標(biāo)準(zhǔn)輸入”的緩存區(qū),所以這時(shí)必須連續(xù)按兩次Ctrl-d。另外,在Windows操作系統(tǒng)下,Ctrl-z代表EOF,所以需要以Ctrl-z結(jié)束。在這之后,gofmt命令會(huì)像從源碼文件中讀取源碼那樣從命令行界面(也稱為標(biāo)準(zhǔn)輸入)讀取源碼,并在格式化后將結(jié)果打印到命令行界面(也稱為標(biāo)準(zhǔn)輸出)中。示例如下:

hc@ubt:~$ gofmt -r='fmt.Println(a)->fmt.Printf("%s\n", a)'
if a=="print" {fmt.Println(a)}                            <----- 在此行的末尾鍵入回車(chē)和Ctrl-d。
warning: rewrite ignored for incomplete programs          <----- 此行及以下就是命令輸出的內(nèi)容。
if a == "print" {
        fmt.Println(a)
}

由上述示例可知,我們可以使用gofmt命令的交互模式格式化任意的代碼片段。雖然會(huì)顯示一行警告信息,但是格式化后的結(jié)果仍然會(huì)被打印出來(lái)。并且,在交互模式下,當(dāng)我們輸入的代碼片段不符合Go語(yǔ)言的語(yǔ)法規(guī)則時(shí),命令程序也會(huì)打印出錯(cuò)誤提示信息。在其它方面,命令程序在交互模式與普通模式下的行為也是基本一致的。

“go fmt命令有什么用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI