日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

十個(gè)令人驚嘆的Go語言技巧,讓你的代碼更加優(yōu)雅

來源: 責(zé)編: 時(shí)間:2023-11-18 09:36:07 292觀看
導(dǎo)讀在開發(fā)生產(chǎn)項(xiàng)目的過程中,我注意到經(jīng)常會(huì)發(fā)現(xiàn)自己在重復(fù)編寫代碼,使用某些技巧時(shí)沒有意識(shí)到,直到后來回顧工作時(shí)才意識(shí)到。為了解決這個(gè)問題,我開發(fā)了一種解決方案,對(duì)我來說非常有幫助,我覺得對(duì)其他人也可能有用。以下是一些

在開發(fā)生產(chǎn)項(xiàng)目的過程中,我注意到經(jīng)常會(huì)發(fā)現(xiàn)自己在重復(fù)編寫代碼,使用某些技巧時(shí)沒有意識(shí)到,直到后來回顧工作時(shí)才意識(shí)到。dl328資訊網(wǎng)——每日最新資訊28at.com

為了解決這個(gè)問題,我開發(fā)了一種解決方案,對(duì)我來說非常有幫助,我覺得對(duì)其他人也可能有用。dl328資訊網(wǎng)——每日最新資訊28at.com

以下是一些從我的實(shí)用程序庫中隨機(jī)挑選的有用且多功能的代碼片段,沒有特定的分類或特定于系統(tǒng)的技巧。dl328資訊網(wǎng)——每日最新資訊28at.com

1. 追蹤執(zhí)行時(shí)間的技巧

如果你想追蹤 Go 中函數(shù)的執(zhí)行時(shí)間,有一個(gè)簡單高效的技巧可以用一行代碼實(shí)現(xiàn),使用 defer 關(guān)鍵字即可。你只需要一個(gè) TrackTime 函數(shù):dl328資訊網(wǎng)——每日最新資訊28at.com

// Utilityfunc TrackTime(pre time.Time) time.Duration {  elapsed := time.Since(pre)  fmt.Println("elapsed:", elapsed)  return elapsed}func TestTrackTime(t *testing.T) {  defer TrackTime(time.Now()) // <--- THIS  time.Sleep(500 * time.Millisecond)}// 輸出:// elapsed: 501.11125ms

1.5. 兩階段延遲執(zhí)行

Go 的 defer 不僅僅是用于清理任務(wù),還可以用于準(zhǔn)備任務(wù),考慮以下示例:dl328資訊網(wǎng)——每日最新資訊28at.com

func setupTeardown() func() {    fmt.Println("Run initialization")    return func() {        fmt.Println("Run cleanup")    }}func main() {    defer setupTeardown()() // <--------    fmt.Println("Main function called")}// 輸出:// Run initialization// Main function called// Run cleanup

這種模式的美妙之處在于,只需一行代碼,你就可以完成諸如以下任務(wù):dl328資訊網(wǎng)——每日最新資訊28at.com

  • 打開數(shù)據(jù)庫連接,然后關(guān)閉它。
  • 設(shè)置模擬環(huán)境,然后拆除它。
  • 獲取分布式鎖,然后釋放它。
  • ...

"嗯,這似乎很聰明,但它在現(xiàn)實(shí)中有什么用處呢?"dl328資訊網(wǎng)——每日最新資訊28at.com

還記得追蹤執(zhí)行時(shí)間的技巧嗎?我們也可以這樣做:dl328資訊網(wǎng)——每日最新資訊28at.com

func TrackTime() func() {  pre := time.Now()  return func() {    elapsed := time.Since(pre)    fmt.Println("elapsed:", elapsed)  }}func main() {  defer TrackTime()()  time.Sleep(500 * time.Millisecond)}

注意!如果我連接到數(shù)據(jù)庫時(shí)出現(xiàn)錯(cuò)誤怎么辦?dl328資訊網(wǎng)——每日最新資訊28at.com

確實(shí),像 defer TrackTime() 或 defer ConnectDB() 這樣的模式不會(huì)妥善處理錯(cuò)誤。這種技巧最適合用于測試或者當(dāng)你愿意冒著致命錯(cuò)誤的風(fēng)險(xiǎn)時(shí)使用,參考下面這種面向測試的方法:dl328資訊網(wǎng)——每日最新資訊28at.com

func TestSomething(t *testing.T) {  defer handleDBConnection(t)()  // ...}func handleDBConnection(t *testing.T) func() {  conn, err := connectDB()  if err != nil {    t.Fatal(err)  }  return func() {    fmt.Println("Closing connection", conn)  }}

這樣,在測試期間可以處理數(shù)據(jù)庫連接的錯(cuò)誤。dl328資訊網(wǎng)——每日最新資訊28at.com

2. 預(yù)分配切片

根據(jù)文章《Go 性能提升技巧》中的見解,預(yù)分配切片或映射可以顯著提高 Go 程序的性能。dl328資訊網(wǎng)——每日最新資訊28at.com

但是值得注意的是,如果我們不小心使用 append 而不是索引(如 a[i]),這種方法有時(shí)可能導(dǎo)致錯(cuò)誤。你知道嗎,我們可以在不指定數(shù)組長度(為零)的情況下使用預(yù)分配的切片,就像在上述文章中解釋的那樣?這使我們可以像使用 append 一樣使用預(yù)分配的切片:dl328資訊網(wǎng)——每日最新資訊28at.com

// 與其a := make([]int, 10)a[0] = 1// 不如這樣使用b := make([]int, 0, 10)b = append(b, 1)

3. 鏈?zhǔn)秸{(diào)用

鏈?zhǔn)秸{(diào)用技術(shù)可以應(yīng)用于函數(shù)(指針)接收器。為了說明這一點(diǎn),讓我們考慮一個(gè) Person 結(jié)構(gòu),它有兩個(gè)函數(shù) AddAge 和 Rename,用于對(duì)其進(jìn)行修改。dl328資訊網(wǎng)——每日最新資訊28at.com

type Person struct {  Name string  Age  int}func (p *Person) AddAge() {  p.Age++}func (p *Person) Rename(name string) {  p.Name = name}

如果你想給一個(gè)人增加年齡然后給他們改名字,常規(guī)的方法是:dl328資訊網(wǎng)——每日最新資訊28at.com

func main() {  p := Person{Name: "Aiden", Age: 30}  p.AddAge()  p.Rename("Aiden 2")}

或者,我們可以修改 AddAge 和 Rename 函數(shù)接收器,使其返回修改后的對(duì)象本身,即使它們通常不返回任何內(nèi)容。dl328資訊網(wǎng)——每日最新資訊28at.com

func (p *Person) AddAge() *Person {  p.Age++  return p}func (p *Person) Rename(name string) *Person {  p.Name = name  return p}

通過返回修改后的對(duì)象本身,我們可以輕松地將多個(gè)函數(shù)接收器鏈在一起,而無需添加不必要的代碼行:dl328資訊網(wǎng)——每日最新資訊28at.com

p = p.AddAge().Rename("Aiden 2")

4. Go 1.20 允許將切片解析為數(shù)組或數(shù)組指針

當(dāng)我們需要將切片轉(zhuǎn)換為固定大小的數(shù)組時(shí),不能直接賦值,例如:dl328資訊網(wǎng)——每日最新資訊28at.com

a := []int{0, 1, 2, 3, 4, 5}var b [3]int = a[0:3]// 在變量聲明中不能將 a[0:3](類型為 []int 的值)賦值給 [3]int 類型的變量// (不兼容的賦值)

為了將切片轉(zhuǎn)換為數(shù)組,Go 團(tuán)隊(duì)在 Go 1.17 中更新了這個(gè)特性。隨著 Go 1.20 的發(fā)布,借助更方便的字面量,轉(zhuǎn)換過程變得更加簡單:dl328資訊網(wǎng)——每日最新資訊28at.com

// Go 1.20func Test(t *testing.T) {   a := []int{0, 1, 2, 3, 4, 5}   b := [3]int(a[0:3])  fmt.Println(b) // [0 1 2]}// Go 1.17func TestM2e(t *testing.T) {  a := []int{0, 1, 2, 3, 4, 5}  b := *(*[3]int)(a[0:3])  fmt.Println(b) // [0 1 2]}

只是一個(gè)快速提醒:你可以使用 a[:3] 替代 a[0:3]。我提到這一點(diǎn)是為了更清晰地說明。dl328資訊網(wǎng)——每日最新資訊28at.com

5. 使用 "import _" 進(jìn)行包初始化

有時(shí),在庫中,你可能會(huì)遇到結(jié)合下劃線 (_) 的導(dǎo)入語句,如下所示:dl328資訊網(wǎng)——每日最新資訊28at.com

import (  _ "google.golang.org/genproto/googleapis/api/annotations")

這將執(zhí)行包的初始化代碼(init 函數(shù)),而無需為其創(chuàng)建名稱引用。這允許你在運(yùn)行代碼之前初始化包、注冊(cè)連接和執(zhí)行其他任務(wù)。dl328資訊網(wǎng)——每日最新資訊28at.com

讓我們通過一個(gè)示例來更好地理解它的工作原理:dl328資訊網(wǎng)——每日最新資訊28at.com

// 下劃線package underscorefunc init() {  fmt.Println("init called from underscore package")}// mainpackage mainimport (  _ "lab/underscore")func main() {}// 輸出:init called from underscore package

6. 使用 "import ." 進(jìn)行導(dǎo)入

在了解了如何使用下劃線進(jìn)行導(dǎo)入后,讓我們看看如何更常見地使用點(diǎn) (.) 運(yùn)算符。dl328資訊網(wǎng)——每日最新資訊28at.com

作為開發(fā)者,點(diǎn) (.) 運(yùn)算符可用于在不必指定包名的情況下使用導(dǎo)入包的導(dǎo)出標(biāo)識(shí)符,這對(duì)于懶惰的開發(fā)者來說是一個(gè)有用的快捷方式。dl328資訊網(wǎng)——每日最新資訊28at.com

很酷,對(duì)吧?這在處理項(xiàng)目中的長包名時(shí)特別有用,比如 externalmodel 或 doingsomethinglonglib。dl328資訊網(wǎng)——每日最新資訊28at.com

為了演示,這里有一個(gè)簡單的例子:dl328資訊網(wǎng)——每日最新資訊28at.com

package mainimport (  "fmt"  . "math")func main() {  fmt.Println(Pi) // 3.141592653589793  fmt.Println(Sin(Pi / 2)) // 1}

7. Go 1.20 允許將多個(gè)錯(cuò)誤合并為單個(gè)錯(cuò)誤

Go 1.20 引入了對(duì)錯(cuò)誤包的新功能,包括對(duì)多個(gè)錯(cuò)誤的支持以及對(duì) errors.Is 和 errors.As 的更改。dl328資訊網(wǎng)——每日最新資訊28at.com

在 errors 中添加的一個(gè)新函數(shù)是 Join,我們將在下面詳細(xì)討論它:dl328資訊網(wǎng)——每日最新資訊28at.com

var (  err1 = errors.New("Error 1st")  err2 = errors.New("Error 2nd"))func main() {  err := err1  err = errors.Join(err, err2)  fmt.Println(errors.Is(err, err1)) // true  fmt.Println(errors.Is(err, err2)) // true}

如果有多個(gè)任務(wù)導(dǎo)致錯(cuò)誤,你可以使用 Join 函數(shù)而不是手動(dòng)管理數(shù)組。這簡化了錯(cuò)誤處理過程。dl328資訊網(wǎng)——每日最新資訊28at.com

8. 檢查接口是否為真正的 nil

即使接口持有的值為 nil,也不意味著接口本身為 nil。這可能導(dǎo)致 Go 程序中的意外錯(cuò)誤。因此,重要的是要知道如何檢查接口是否為真正的 nil。dl328資訊網(wǎng)——每日最新資訊28at.com

func main() {  var x interface{}  var y *int = nil  x = y  if x != nil {    fmt.Println("x != nil") // <-- 實(shí)際輸出  } else {    fmt.Println("x == nil")  }  fmt.Println(x)}// 輸出:// x != nil// <nil>

我們?nèi)绾未_定 interface{} 值是否為 nil 呢?幸運(yùn)的是,有一個(gè)簡單的工具可以幫助我們實(shí)現(xiàn)這一點(diǎn):dl328資訊網(wǎng)——每日最新資訊28at.com

func IsNil(x interface{}) bool {  if x == nil {    return true  }  return reflect.ValueOf(x).IsNil()}

9. 在 JSON 中解析 time.Duration

當(dāng)解析 JSON 時(shí),使用 time.Duration 可能是一個(gè)繁瑣的過程,因?yàn)樗枰谝幻氲暮竺嫣砑?9 個(gè)零(即 1000000000)。為了簡化這個(gè)過程,我創(chuàng)建了一個(gè)名為 Duration 的新類型:dl328資訊網(wǎng)——每日最新資訊28at.com

type Duration time.Duration

為了將字符串(如 "1s" 或 "20h5m")解析為 int64 類型的持續(xù)時(shí)間,我還為這個(gè)新類型實(shí)現(xiàn)了自定義的解析邏輯:dl328資訊網(wǎng)——每日最新資訊28at.com

func (d *Duration) UnmarshalJSON(b []byte) error {  var s string  if err := json.Unmarshal(b, &s); err != nil {    return err  }  dur, err := time.ParseDuration(s)  if err != nil {    return err  }  *d = Duration(dur)  return nil}

但是,需要注意的是,變量 'd' 不應(yīng)為 nil,否則可能會(huì)導(dǎo)致編組錯(cuò)誤。或者,你還可以在函數(shù)開頭對(duì) 'd' 進(jìn)行檢查。dl328資訊網(wǎng)——每日最新資訊28at.com

10. 避免裸參數(shù)

當(dāng)處理具有多個(gè)參數(shù)的函數(shù)時(shí),僅通過閱讀其用法來理解每個(gè)參數(shù)的含義可能會(huì)令人困惑。考慮以下示例:dl328資訊網(wǎng)——每日最新資訊28at.com

printInfo("foo", true, true)

如果不檢查 printInfo 函數(shù),那么第一個(gè) 'true' 和第二個(gè) 'true' 的含義是什么呢?當(dāng)你有一個(gè)具有多個(gè)參數(shù)的函數(shù)時(shí),僅通過閱讀其用法來理解參數(shù)的含義可能會(huì)令人困惑。dl328資訊網(wǎng)——每日最新資訊28at.com

但是,我們可以使用注釋使代碼更易讀。例如:dl328資訊網(wǎng)——每日最新資訊28at.com

// func printInfo(name string, isLocal, done bool)printInfo("foo", true /* isLocal */, true /* done */)

有些 IDE 也支持這個(gè)功能,可以在函數(shù)調(diào)用建議中顯示注釋,但可能需要在設(shè)置中啟用。dl328資訊網(wǎng)——每日最新資訊28at.com

以上是我分享的一些實(shí)用技巧,但我不想讓文章過長,難以跟進(jìn),因?yàn)檫@些技巧與特定主題無關(guān),涵蓋了各種類別。dl328資訊網(wǎng)——每日最新資訊28at.com

如果你覺得這些技巧有用,或有自己的見解要分享,請(qǐng)隨時(shí)留言。我重視你的反饋,并樂于在回應(yīng)此文章時(shí)點(diǎn)贊或推薦你的想法。dl328資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-28347-0.html十個(gè)令人驚嘆的Go語言技巧,讓你的代碼更加優(yōu)雅

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 突發(fā)!OpenAI的CEO被開了...

下一篇: 微信支付V3版本集成詳解【避坑指南】

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 一加Ace2 Pro真機(jī)揭曉 鈦空灰配色質(zhì)感拉滿

    終于,在經(jīng)過了幾波預(yù)熱之后,一加Ace2 Pro的外觀真機(jī)圖在網(wǎng)上出現(xiàn)了。還是博主數(shù)碼閑聊站曝光的,這次的外觀設(shè)計(jì)還是延續(xù)了一加11的方案,只是細(xì)節(jié)上有了調(diào)整,例如新加入了鈦空灰
  • 直屏旗艦來了 iQOO 12和K70 Pro同臺(tái)競技

    旗艦機(jī)基本上使用的都是雙曲面屏幕,這就讓很多喜歡直屏的愛好者在苦等一款直屏旗艦,這次,你們等到了。據(jù)博主數(shù)碼閑聊站帶來的最新爆料稱,Redmi下代旗艦K70 Pro和iQOO 12兩款手
  • 一篇聊聊Go錯(cuò)誤封裝機(jī)制

    %w 是用于錯(cuò)誤包裝(Error Wrapping)的格式化動(dòng)詞。它是用于 fmt.Errorf 和 fmt.Sprintf 函數(shù)中的一個(gè)特殊格式化動(dòng)詞,用于將一個(gè)錯(cuò)誤(或其他可打印的值)包裝在一個(gè)新的錯(cuò)誤中。使
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動(dòng)設(shè)備上有一個(gè)固定元素,當(dāng)激活虛擬鍵盤時(shí),該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認(rèn)行為,在本文中,我們將探討這個(gè)問題、為什么會(huì)發(fā)生
  • 2023年,我眼中的字節(jié)跳動(dòng)

    此時(shí)此刻(2023年7月),字節(jié)跳動(dòng)從未上市,也從未公布過任何官方的上市計(jì)劃;但是這并不妨礙它成為中國最受關(guān)注的互聯(lián)網(wǎng)公司之一。從2016-17年的抖音強(qiáng)勢(shì)崛起,到2018年的&ldquo;頭騰
  • 梁柱接棒兩年,騰訊音樂闖出新路子

    文丨田靜 出品丨牛刀財(cái)經(jīng)(niudaocaijing)7月5日,企鵝FM發(fā)布官方公告稱由于業(yè)務(wù)調(diào)整,將于9月6日正式停止運(yùn)營,這意味著騰訊音樂長音頻業(yè)務(wù)走向消亡。騰訊在長音頻領(lǐng)域還在摸索。為
  • 三星Galaxy Z Fold5今日亮相:厚度縮減但仍略顯厚重

    據(jù)官方此前宣布,三星將于7月26日也就是今天在韓國首爾舉辦Unpacked活動(dòng),屆時(shí)將帶來帶來包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy
  • iQOO Neo8系列或定檔5月23日:首發(fā)天璣9200+ 安卓跑分王者

    去年10月,iQOO推出了iQOO Neo7系列機(jī)型,不僅搭載了天璣9000+,而且是同價(jià)位唯一一款天璣9000+直屏旗艦,一經(jīng)上市便受到了用戶的廣泛關(guān)注。在時(shí)隔半年后,
  • 質(zhì)感不錯(cuò)!OPPO K11渲染圖曝光:旗艦IMX890傳感器首次下放

    一直以來,OPPO K系列機(jī)型都保持著較為均衡的產(chǎn)品體驗(yàn),歷來都是2K價(jià)位的明星機(jī)型,去年推出的OPPO K10和OPPO K10 Pro兩款機(jī)型憑借各自的出色配置,堪稱有
Top 主站蜘蛛池模板: 子长县| 中西区| 西乡县| 岢岚县| 固镇县| 屏南县| 弋阳县| 石渠县| 永福县| 山西省| 古蔺县| 罗田县| 唐山市| 泰安市| 汽车| 西城区| 株洲市| 焉耆| 武强县| 沛县| 章丘市| 芦溪县| 万安县| 阳西县| 沐川县| 读书| 金阳县| 静安区| 寿光市| 白山市| 邢台市| 工布江达县| 桃园市| 西充县| 襄垣县| 武义县| 车致| 通化县| 东乡县| 柳州市| 册亨县|