欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang與其他語言不同的九個特性

 更新時間:2021年09月23日 09:38:49   作者:海擁✘  
近來關(guān)于對Golang的討論有很多,七牛的幾個大牛們也斷定Go語言在未來將會快速發(fā)展,并且很可能會取代Java成為互聯(lián)網(wǎng)時代最受歡迎的編程語言。本文將帶你了解它不同于其他語言的九個特性

隨著編程語言的發(fā)展,Go 還很年輕。它于 2009 年 11 月 10 日首次發(fā)布。其創(chuàng)建者Robert Griesemer
Rob Pike 和 Ken Thompson在 Google 工作,在那里大規(guī)模擴(kuò)展的挑戰(zhàn)激勵他們將 Go 設(shè)計為一種快速有效的編程解決方案,用于具有大型代碼庫、管理由多個開發(fā)人員,具有嚴(yán)格的性能要求,并跨越多個網(wǎng)絡(luò)和處理核心。
Go 的創(chuàng)始人在創(chuàng)建他們的新語言時也借此機(jī)會學(xué)習(xí)了其他編程語言的優(yōu)點、缺點和漏洞。結(jié)果是一種干凈、清晰和實用的語言,具有相對較少的命令和功能集。

在本文中,今天這篇文章將給大家介紹一下 Go 與其他語言不同的 9 個特性。

1. Go 總是在構(gòu)建中包含二進(jìn)制文件

Go 運(yùn)行時提供內(nèi)存分配、垃圾收集、并發(fā)支持和網(wǎng)絡(luò)等服務(wù)。它被編譯到每個 Go 二進(jìn)制文件中。這與許多其他語言不同,其中許多語言使用需要與程序一起安裝才能正常工作的虛擬機(jī)。

將運(yùn)行時直接包含在二進(jìn)制文件中使得分發(fā)和運(yùn)行 Go 程序變得非常容易,并避免了運(yùn)行時和程序之間的不兼容問題。Python、Ruby 和 JavaScript 等語言的虛擬機(jī)也沒有針對垃圾收集和內(nèi)存分配進(jìn)行優(yōu)化,這解釋了 Go 相對于其他類似語言的優(yōu)越速度。例如,Go 將盡可能多的存儲在堆棧中,其中數(shù)據(jù)按順序排列以便比堆更快地訪問。稍后會詳細(xì)介紹。

關(guān)于 Go 的靜態(tài)二進(jìn)制文件的最后一件事是,因為不需要運(yùn)行外部依賴項,所以它們啟動得非???。如果您使用Google App Engine 之類的服務(wù),這是一種在 Google Cloud 上運(yùn)行的平臺即服務(wù),它可以將您的應(yīng)用程序縮減到零實例以節(jié)省云成本,這將非常有用。當(dāng)收到新請求時,App Engine 可以在眨眼間啟動 Go 程序的一個實例。在 Python 或 Node 中的相同體驗通常會導(dǎo)致 3-5 秒(或更長時間)的等待,因為所需的虛擬環(huán)境也會與新實例一起啟動。

2. Go 沒有針對程序依賴的集中托管服務(wù)

為了訪問已發(fā)布的 Go 程序,開發(fā)人員不依賴集中托管的服務(wù),例如Java 的Maven Central或JavaScript的NPM注冊表。相反,項目通過其源代碼存儲庫(最常見的是 Github)共享。在go install命令行允許以這種方式下載庫。
為什么我喜歡這個功能?我一直認(rèn)為像 Maven Central、PIP 和 NPM 這樣的集中托管的依賴服務(wù)有點令人生畏的黑盒子,也許可以抽象出下載和安裝依賴項的麻煩,但不可避免地會在依賴項錯誤時引發(fā)可怕的心跳停止發(fā)生。

此外,將的的模塊提供給其他人就像將其放入版本控制系統(tǒng)一樣簡單,這是分發(fā)程序的一種非常簡單的方式。

3. Go 是按值調(diào)用的

在 Go 中,當(dāng)你提供一個原始值(數(shù)字、布爾值或字符串)或一個結(jié)構(gòu)體(類對象的粗略等價物)作為函數(shù)的參數(shù)時,Go 總是會復(fù)制變量的值。

在 Java、Python 和 JavaScript 等許多其他語言中,原語是按值傳遞的,但對象(類實例)是按引用傳遞的,這意味著接收函數(shù)實際上接收的是指向原始對象的指針,而不是其副本。在接收函數(shù)中對對象所做的任何更改都會反映在原始對象中。

在 Go 中,結(jié)構(gòu)體和原語默認(rèn)按值傳遞,可以選擇傳遞指針,通過使用星號運(yùn)算符:

// 按值傳遞
func MakeNewFoo(f Foo ) (Foo, error) { 
   f.Field1 = "New val" 
   f.Field2 = f.Field2 + 1 
   return f, nil 
}

上述函數(shù)接收 Foo 的副本并返回一個新的 Foo 對象。

// 通過引用傳遞
func MutateFoo(f *Foo ) error { 
   f.Field1 = "New val" 
   f.Field2 = 2 
   return nil 
}

上面的函數(shù)接收一個指向 Foo 的指針并改變原始對象。

按值調(diào)用與按引用調(diào)用的這種明顯區(qū)別使您的意圖顯而易見,并降低了調(diào)用函數(shù)無意中改變傳入對象的可能性(當(dāng)它不應(yīng)該發(fā)生時(許多初學(xué)者開發(fā)人員很難做到這一點)握緊)。

正如麻省理工總結(jié)的:“可變性使得理解你的程序在做什么變得更加困難,并且更難以執(zhí)行契約”

此外,按值調(diào)用顯著減少了垃圾收集器的工作,這意味著應(yīng)用程序更快、內(nèi)存效率更高。這篇文章得出的結(jié)論是,指針追蹤(從堆中檢索指針值)比從連續(xù)堆棧中檢索值慢 10 到 20 倍。要記住的一個很好的經(jīng)驗法則是:從內(nèi)存中讀取的最快方法是順序讀取,這意味著將隨機(jī)存儲在 RAM 中的指針數(shù)量減少到最少。

4. ‘defer' 關(guān)鍵字

在NodeJS 中,在我開始使用knex.js之前,我會通過創(chuàng)建一個數(shù)據(jù)庫池來手動管理我的代碼中的數(shù)據(jù)庫連接,然后在每個函數(shù)中從池中打開一個新連接,一旦所需的數(shù)據(jù)庫 CRUD 功能已完成。

這有點像維護(hù)噩夢,因為如果我沒有在每個函數(shù)結(jié)束時釋放連接,未釋放的數(shù)據(jù)庫連接的數(shù)量會慢慢增長,直到池中沒有更多可用連接,然后中斷應(yīng)用程序。

現(xiàn)實情況是,程序經(jīng)常需要釋放、清理和拆除資源、文件、連接等,因此 Go 引入了defer關(guān)鍵字作為管理這些的有效方式。

任何以defer開頭的語句都會延遲對它的調(diào)用,直到周圍的函數(shù)退出。這意味著您可以將清理/拆卸代碼放在函數(shù)的頂部(很明顯),知道一旦函數(shù)完成它就會如此。

func main() {                        
    if len(os.Args) < 2 {   
        log.Fatal("no file specified")
    }  
    f, err := os.Open(os.Args[1])                        
    if err != nil {                         
        log.Fatal(err)                        
    }                        
    defer f.Close()                        
    data := make([]byte, 2048)                        
    for {                         
        count, err := f.Read(data)                                               
        os.Stdout.Write(data[:count])                        
        if err != nil {                          
            if err != io.EOF {                           
                log.Fatal(err)                          
            }                          
            break                         
        }                        
    }                       
}

在上面的例子中,文件關(guān)閉方法被推遲了。我喜歡這種在函數(shù)頂部聲明你的內(nèi)務(wù)處理意圖的模式,然后忘記它,知道一旦函數(shù)退出它就會完成它的工作。

5. Go 采用了函數(shù)式編程的最佳特性

函數(shù)式編程是一種高效且富有創(chuàng)造性的范式,幸運(yùn)的是 Go 采用了函數(shù)式編程的最佳特性。在Go中:

  • 函數(shù)是值,這意味著它們可以作為值添加到映射中,作為參數(shù)傳遞給其他函數(shù),設(shè)置為變量,并從函數(shù)返回(稱為“高階函數(shù)”,在 Go 中經(jīng)常使用裝飾器創(chuàng)建中間件圖案)。
  • 可以創(chuàng)建和自動調(diào)用匿名函數(shù)。
  • 在其他函數(shù)內(nèi)聲明的函數(shù)允許閉包(在函數(shù)內(nèi)聲明的函數(shù)能夠訪問和修改在外部函數(shù)中聲明的變量)。在慣用的 Go 中,閉包被廣泛使用來限制函數(shù)的范圍,并設(shè)置函數(shù)然后在其邏輯中使用的狀態(tài)。
func StartTimer (name string) func(){
    t := time.Now()
    log.Println(name, "started")
    return func() {
        d := time.Now().Sub(t)
        log.Println(name, "took", d)
    }
}
func RunTimer() {
    stop := StartTimer("My timer")
    defer stop()
    time.Sleep(1 * time.Second)
}

上面是一個閉包的例子?!甋tartTimer' 函數(shù)返回一個新函數(shù),它通過閉包可以訪問在其出生范圍內(nèi)設(shè)置的 ‘t' 值。然后,此函數(shù)可以將當(dāng)前時間與“t”的值進(jìn)行比較,從而創(chuàng)建一個有用的計時器。感謝Mat Ryer的這個例子。

6. Go 有隱式接口

任何閱讀過有關(guān)SOLID編碼和設(shè)計模式的文獻(xiàn)的人都可能聽說過“優(yōu)先組合勝過繼承”的口頭禪。簡而言之,這表明您應(yīng)該將業(yè)務(wù)邏輯分解為不同的接口,而不是依賴于來自父類的屬性和邏輯的分層繼承。

另一個流行的方法是“為接口編程,而不是實現(xiàn)”: API 應(yīng)該只發(fā)布其預(yù)期行為的契約(其方法簽名),而不是有關(guān)如何實現(xiàn)該行為的詳細(xì)信息。

這兩者都表明接口在現(xiàn)代編程中的重要性。

因此,Go 支持接口也就不足為奇了。事實上,接口是 Go 中唯一的抽象類型。

然而,與其他語言不同,Go 中的接口不是顯式實現(xiàn)的,而是隱式實現(xiàn)的。具體類型不聲明它實現(xiàn)了接口。相反,如果為該具體類型設(shè)置的方法集包含底層接口的所有方法集,則Go 認(rèn)為該對象實現(xiàn)了 interface。

這種隱式接口實現(xiàn)(正式稱為結(jié)構(gòu)類型)允許 Go 強(qiáng)制執(zhí)行類型安全和解耦,保持動態(tài)語言中表現(xiàn)出的大部分靈活性。

相比之下,顯式接口將客戶端和實現(xiàn)綁定在一起,例如,在 Java 中替換依賴項比在 Go 中困難得多。

// 這是一個接口聲明(稱為Logic)
type Logic interface { 
    Process (data string) string 
}

type LogicProvider struct {}
// 這是 LogicProvider 上名為“Process”的方法 struct
 func (lp LogicProvider) Process (data string) string { 
    // 業(yè)務(wù)邏輯
}
// 這是具有 Logic 接口作為屬性的客戶端結(jié)構(gòu)
type Client struct { 
    L Logic 
}
func(c Client) Program() { 
    // 從某處獲取數(shù)據(jù)
    cLProcess(data) 
}
func main() { 
    c := Client { 
        L: LogicProvider{},  
     } 
    c.Program() 
}

LogicProvider 中沒有任何聲明表示它符合Logic接口。這意味著客戶端將來可以輕松替換其邏輯提供程序,只要該邏輯提供程序包含底層接口 ( Logic ) 的所有方法集。

7.錯誤處理

Go 中的錯誤處理方式與其他語言大不相同。簡而言之,Go 通過返回一個 error 類型的值作為函數(shù)的最后一個返回值來處理錯誤。

當(dāng)函數(shù)按預(yù)期執(zhí)行時,錯誤參數(shù)返回nil,否則返回錯誤值。調(diào)用函數(shù)然后檢查錯誤返回值,并處理錯誤,或拋出自己的錯誤。

// 函數(shù)返回一個整數(shù)和一個錯誤
func calculateRemainder(numerator int, denominator int) ( int, error ) { 
   //
   if denominator == 0 { 
      return 9, errors.New("denominator is 0"
    }
   // 沒有錯誤返回
   return numerator / denominator, nil
 }

Go 以這種方式運(yùn)行是有原因的:它迫使編碼人員考慮異常并正確處理它們。傳統(tǒng)的 try-catch 異常還會在代碼中添加至少一個新的代碼路徑,并以難以遵循的方式縮進(jìn)代碼。Go 更喜歡將“快樂路徑”視為非縮進(jìn)代碼,在“快樂路徑”完成之前識別并返回任何錯誤。

8.并發(fā)

可以說是 Go 最著名的特性,并發(fā)允許處理在機(jī)器或服務(wù)器上的可用內(nèi)核數(shù)量上并行運(yùn)行。當(dāng)單獨的進(jìn)程不相互依賴(不需要順序運(yùn)行)并且時間性能至關(guān)重要時,并發(fā)性最有意義。這通常是 I/O 要求的情況,其中讀取或?qū)懭氪疟P或網(wǎng)絡(luò)的速度比除最復(fù)雜的內(nèi)存中進(jìn)程之外的所有進(jìn)程慢幾個數(shù)量級。
函數(shù)調(diào)用前的“ go ”關(guān)鍵字將同時運(yùn)行該函數(shù)。

func process(val int) int { 
   // 用 val 做一些事情
}
// 對于 'in' 中的每個值,同時運(yùn)行 process 函數(shù),
// 并將 process 的結(jié)果讀取到 'out'
 func runConcurrently(in <-chan int, out chan<- int){ 
   go func() { 
       for val := range in { 
            result := process(val) 
            out <- result   
       } 
   } 
}

Go 中的并發(fā)是一項深入且相當(dāng)高級的功能,但在有意義的地方,它提供了一種有效的方法來確保程序的最佳性能。

9. Go 標(biāo)準(zhǔn)庫

Go 有一個“包含電池”的理念,現(xiàn)代編程語言的許多要求都被納入標(biāo)準(zhǔn)庫,這使程序員的生活變得更加簡單。
如前所述,Go 是一種相對年輕的語言,這意味著標(biāo)準(zhǔn)庫中可以滿足現(xiàn)代應(yīng)用程序的許多問題/要求。

一方面,Go 為網(wǎng)絡(luò)(特別是 HTTP/2)和文件管理提供了世界一流的支持。它還提供原生 JSON 編碼和解碼。因此,設(shè)置服務(wù)器來處理 HTTP 請求并返回響應(yīng)(JSON 或其他)非常簡單,這解釋了 Go 在基于 REST 的 HTTP Web 服務(wù)開發(fā)中的流行。

正如Mat Ryer還指出的那樣,標(biāo)準(zhǔn)庫是開源的,是學(xué)習(xí) Go 最佳實踐的絕佳方式。

如果你真的從這篇文章中學(xué)到了一些新東西,喜歡它,收藏它并與你的小伙伴分享。🤗最后,不要忘了❤或📑支持一下哦

到此這篇關(guān)于Golang與其他語言不同的九個特性的文章就介紹到這了,更多相關(guān)Golang 特性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語言實現(xiàn)一個簡單的http客戶端抓取遠(yuǎn)程url的方法

    go語言實現(xiàn)一個簡單的http客戶端抓取遠(yuǎn)程url的方法

    這篇文章主要介紹了go語言實現(xiàn)一個簡單的http客戶端抓取遠(yuǎn)程url的方法,實例分析了Go語言http操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • golang判斷字符串是是否包含另一字符串的示例代碼

    golang判斷字符串是是否包含另一字符串的示例代碼

    在Go語言中,可以使用strings.Contains()函數(shù)來判斷一個字符串是否包含另一個字符串,該函數(shù)接受兩個參數(shù):要搜索的字符串和要查找的子字符串,如果子字符串存在于要搜索的字符串中,則返回true,否則返回false,下面通過示例詳細(xì)介紹,感興趣的朋友一起看看吧
    2023-09-09
  • 利用Go語言實現(xiàn)在終端繪制小兔子

    利用Go語言實現(xiàn)在終端繪制小兔子

    這篇文章主要為大家詳細(xì)介紹了如何利用Go語言實現(xiàn)在終端繪制小兔子來給大家拜個早年,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-01-01
  • 秒懂Golang匿名函數(shù)

    秒懂Golang匿名函數(shù)

    所謂匿名函數(shù),就是沒有名字的函數(shù),本文重點給大家介紹Golang匿名函數(shù)的相關(guān)知識,通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • 一文帶你了解Go語言中方法的調(diào)用

    一文帶你了解Go語言中方法的調(diào)用

    這篇文章主要和大家分享一下Go語言中的方法的調(diào)用,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Go語言有一定的幫助,需要的小伙伴可以參考一下
    2022-12-12
  • Makefile構(gòu)建Golang項目示例詳解

    Makefile構(gòu)建Golang項目示例詳解

    這篇文章主要為大家介紹了Makefile構(gòu)建Golang項目的過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go語言開源庫實現(xiàn)Onvif協(xié)議客戶端設(shè)備搜索

    Go語言開源庫實現(xiàn)Onvif協(xié)議客戶端設(shè)備搜索

    這篇文章主要為大家介紹了Go語言O(shè)nvif協(xié)議客戶端設(shè)備搜索示例實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Go字典使用詳解

    Go字典使用詳解

    今天和大家一起學(xué)習(xí)Go語言的字典。Go語言的字典又稱為map,一種使用廣泛的數(shù)據(jù)結(jié)構(gòu)。它是擁有key/value對元素的「無序集合」,而且在集合中key必須是唯一的
    2022-11-11
  • golang 打印error的堆棧信息操作

    golang 打印error的堆棧信息操作

    這篇文章主要介紹了golang 打印error的堆棧信息操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 使用IDEA配置GO語言的開發(fā)環(huán)境備忘錄

    使用IDEA配置GO語言的開發(fā)環(huán)境備忘錄

    最近在配置idea開發(fā)go語言時碰到很多問題,想著很多人都可能會遇到,所以下面這篇文章主要給大家介紹了關(guān)于使用IDEA配置GO語言的開發(fā)環(huán)境,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05

最新評論