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

當前位置:首頁 > 科技  > 軟件

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

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

在開發(fā)生產項目的過程中,我注意到經常會發(fā)現自己在重復編寫代碼,使用某些技巧時沒有意識到,直到后來回顧工作時才意識到。K5T28資訊網——每日最新資訊28at.com

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

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

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

如果你想追蹤 Go 中函數的執(zhí)行時間,有一個簡單高效的技巧可以用一行代碼實現,使用 defer 關鍵字即可。你只需要一個 TrackTime 函數:K5T28資訊網——每日最新資訊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 不僅僅是用于清理任務,還可以用于準備任務,考慮以下示例:K5T28資訊網——每日最新資訊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

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

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

"嗯,這似乎很聰明,但它在現實中有什么用處呢?"K5T28資訊網——每日最新資訊28at.com

還記得追蹤執(zhí)行時間的技巧嗎?我們也可以這樣做:K5T28資訊網——每日最新資訊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)}

注意!如果我連接到數據庫時出現錯誤怎么辦?K5T28資訊網——每日最新資訊28at.com

確實,像 defer TrackTime() 或 defer ConnectDB() 這樣的模式不會妥善處理錯誤。這種技巧最適合用于測試或者當你愿意冒著致命錯誤的風險時使用,參考下面這種面向測試的方法:K5T28資訊網——每日最新資訊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)  }}

這樣,在測試期間可以處理數據庫連接的錯誤。K5T28資訊網——每日最新資訊28at.com

2. 預分配切片

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

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

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

3. 鏈式調用

鏈式調用技術可以應用于函數(指針)接收器。為了說明這一點,讓我們考慮一個 Person 結構,它有兩個函數 AddAge 和 Rename,用于對其進行修改。K5T28資訊網——每日最新資訊28at.com

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

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

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

或者,我們可以修改 AddAge 和 Rename 函數接收器,使其返回修改后的對象本身,即使它們通常不返回任何內容。K5T28資訊網——每日最新資訊28at.com

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

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

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

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

當我們需要將切片轉換為固定大小的數組時,不能直接賦值,例如:K5T28資訊網——每日最新資訊28at.com

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

為了將切片轉換為數組,Go 團隊在 Go 1.17 中更新了這個特性。隨著 Go 1.20 的發(fā)布,借助更方便的字面量,轉換過程變得更加簡單:K5T28資訊網——每日最新資訊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]}

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

5. 使用 "import _" 進行包初始化

有時,在庫中,你可能會遇到結合下劃線 (_) 的導入語句,如下所示:K5T28資訊網——每日最新資訊28at.com

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

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

讓我們通過一個示例來更好地理解它的工作原理:K5T28資訊網——每日最新資訊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 ." 進行導入

在了解了如何使用下劃線進行導入后,讓我們看看如何更常見地使用點 (.) 運算符。K5T28資訊網——每日最新資訊28at.com

作為開發(fā)者,點 (.) 運算符可用于在不必指定包名的情況下使用導入包的導出標識符,這對于懶惰的開發(fā)者來說是一個有用的快捷方式。K5T28資訊網——每日最新資訊28at.com

很酷,對吧?這在處理項目中的長包名時特別有用,比如 externalmodel 或 doingsomethinglonglib。K5T28資訊網——每日最新資訊28at.com

為了演示,這里有一個簡單的例子:K5T28資訊網——每日最新資訊28at.com

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

7. Go 1.20 允許將多個錯誤合并為單個錯誤

Go 1.20 引入了對錯誤包的新功能,包括對多個錯誤的支持以及對 errors.Is 和 errors.As 的更改。K5T28資訊網——每日最新資訊28at.com

在 errors 中添加的一個新函數是 Join,我們將在下面詳細討論它:K5T28資訊網——每日最新資訊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}

如果有多個任務導致錯誤,你可以使用 Join 函數而不是手動管理數組。這簡化了錯誤處理過程。K5T28資訊網——每日最新資訊28at.com

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

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

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

我們如何確定 interface{} 值是否為 nil 呢?幸運的是,有一個簡單的工具可以幫助我們實現這一點:K5T28資訊網——每日最新資訊28at.com

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

9. 在 JSON 中解析 time.Duration

當解析 JSON 時,使用 time.Duration 可能是一個繁瑣的過程,因為它需要在一秒的后面添加 9 個零(即 1000000000)。為了簡化這個過程,我創(chuàng)建了一個名為 Duration 的新類型:K5T28資訊網——每日最新資訊28at.com

type Duration time.Duration

為了將字符串(如 "1s" 或 "20h5m")解析為 int64 類型的持續(xù)時間,我還為這個新類型實現了自定義的解析邏輯:K5T28資訊網——每日最新資訊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' 不應為 nil,否則可能會導致編組錯誤。或者,你還可以在函數開頭對 'd' 進行檢查。K5T28資訊網——每日最新資訊28at.com

10. 避免裸參數

當處理具有多個參數的函數時,僅通過閱讀其用法來理解每個參數的含義可能會令人困惑。考慮以下示例:K5T28資訊網——每日最新資訊28at.com

printInfo("foo", true, true)

如果不檢查 printInfo 函數,那么第一個 'true' 和第二個 'true' 的含義是什么呢?當你有一個具有多個參數的函數時,僅通過閱讀其用法來理解參數的含義可能會令人困惑。K5T28資訊網——每日最新資訊28at.com

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

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

有些 IDE 也支持這個功能,可以在函數調用建議中顯示注釋,但可能需要在設置中啟用。K5T28資訊網——每日最新資訊28at.com

以上是我分享的一些實用技巧,但我不想讓文章過長,難以跟進,因為這些技巧與特定主題無關,涵蓋了各種類別。K5T28資訊網——每日最新資訊28at.com

如果你覺得這些技巧有用,或有自己的見解要分享,請隨時留言。我重視你的反饋,并樂于在回應此文章時點贊或推薦你的想法。K5T28資訊網——每日最新資訊28at.com

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

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

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

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

標簽:
  • 熱門焦點
  • 印度登月最關鍵一步!月船三號今晚進入環(huán)月軌道

    8月5日消息,據印度官方消息,月船三號將于北京時間今晚21時30分左右開始近月制動進入環(huán)月軌道。這是該探測器能夠成功的最關鍵步驟之一,如果成功將開始圍
  • 十個簡單但很有用的Python裝飾器

    裝飾器(Decorators)是Python中一種強大而靈活的功能,用于修改或增強函數或類的行為。裝飾器本質上是一個函數,它接受另一個函數或類作為參數,并返回一個新的函數或類。它們通常用
  • 一篇文章帶你了解 CSS 屬性選擇器

    屬性選擇器對帶有指定屬性的 HTML 元素設置樣式。可以為擁有指定屬性的 HTML 元素設置樣式,而不僅限于 class 和 id 屬性。一、了解屬性選擇器CSS屬性選擇器提供了一種簡單而
  • 從零到英雄:高并發(fā)與性能優(yōu)化的神奇之旅

    作者 | 波哥審校 | 重樓作為公司的架構師或者程序員,你是否曾經為公司的系統(tǒng)在面對高并發(fā)和性能瓶頸時感到手足無措或者焦頭爛額呢?筆者在出道那會為此是吃盡了苦頭的,不過也得
  • 零售大模型“干中學”,攀爬數字化珠峰

    文/侯煜編輯/cc來源/華爾街科技眼對于絕大多數登山愛好者而言,攀爬珠穆朗瑪峰可謂終極目標。攀登珠峰的商業(yè)路線有兩條,一是尼泊爾境內的南坡路線,一是中國境內的北坡路線。相
  • 雅柏威士忌多款單品價格大跌,泥煤頂流也不香了?

    來源 | 烈酒商業(yè)觀察編 | 肖海林今年以來,威士忌市場開始出現了降溫跡象,越來越多不斷暴漲的網紅威士忌也開始悄然回歸市場理性。近日,LVMH集團旗下蘇格蘭威士忌品牌雅柏(Ardbeg
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • 猿輔導與新東方的兩種“歸途”

    作者|卓心月 出品|零態(tài)LT(ID:LingTai_LT)如何成為一家偉大企業(yè)?答案一定是對&ldquo;勢&rdquo;的把握,這其中最關鍵的當屬對企業(yè)戰(zhàn)略的制定,且能夠站在未來看現在,即使這其中的
  • 蘋果公司要求三星和LG Display生產「無邊框」OLED iPhone顯示屏

    據 The Elec 報道,蘋果已要求其供應商為未來的 iPhone 型號開發(fā)「無邊框」OLED 顯示面板。蘋果顯然已要求三星和 LG Display 開發(fā)新的 OLED 顯示面
Top 主站蜘蛛池模板: 祁门县| 广灵县| 溆浦县| 永城市| 临泉县| 房产| 江西省| 黑龙江省| 余姚市| 青田县| 吴忠市| 东丰县| 咸阳市| 曲周县| 邻水| 纳雍县| 肥乡县| 海原县| 寻甸| 台湾省| 井陉县| 布尔津县| 关岭| 马龙县| 礼泉县| 南丰县| 洮南市| 石家庄市| 宽甸| 咸宁市| 杭锦后旗| 三江| 渭南市| 文水县| 五华县| 临夏市| 福建省| 重庆市| 肇源县| 荥经县| 安顺市|