国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

這篇具有很好參考價(jià)值的文章主要介紹了云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

@

目錄
  • 概述
    • 定義
    • 使用場(chǎng)景
    • Go 安全
  • 使用須知
    • 搜索工具
    • Go基礎(chǔ)命令
    • 標(biāo)準(zhǔn)庫(kù)
  • 基礎(chǔ)語(yǔ)法
    • Effective Go 概覽
    • 命名規(guī)范
    • 注釋
    • 變量
    • 常量(const)
    • 控制結(jié)構(gòu)
    • 數(shù)據(jù)類型
    • 迭代(range)
    • 函數(shù)
    • 指針
    • 字符串和符文
    • 結(jié)構(gòu)體(struct)
    • 方法
    • 接口(interface)
    • 泛型
    • 錯(cuò)誤(errors)
    • 恐慌(pinic)
    • 推遲(defer)
    • 恢復(fù)(recover)

概述

定義

Go 官網(wǎng)地址 https://golang.google.cn/ 最新版本1.20.3

Go 官網(wǎng)文檔地址 https://golang.google.cn/doc/

Go 源碼地址 https://github.com/golang

Golang簡(jiǎn)稱Go,是谷歌開(kāi)源的編程語(yǔ)言,旨在提供程序員編程效率,易于學(xué)習(xí),非常適合團(tuán)隊(duì)使用,天然支持高并發(fā),有垃圾收集機(jī)制,且自帶功能完善健壯的標(biāo)準(zhǔn)庫(kù)。

Go語(yǔ)言表現(xiàn)力強(qiáng)、簡(jiǎn)潔、干凈、高效。它的并發(fā)機(jī)制使得其容易編寫出充分利用多核和網(wǎng)絡(luò)機(jī)器的程序,其類型系統(tǒng)使程序構(gòu)造變得靈活和模塊化。Go可以快速編譯為機(jī)器碼,并且具有垃圾收集的便利性和運(yùn)行時(shí)反射的強(qiáng)大功能;是一種快速的、靜態(tài)類型的編譯語(yǔ)言,感覺(jué)像是一種動(dòng)態(tài)類型的解釋語(yǔ)言。

Go語(yǔ)言由于來(lái)自全球技術(shù)大廠谷歌創(chuàng)造及推動(dòng),其生態(tài)發(fā)展極其迅速,從業(yè)界聲音看大有可能成為接下來(lái)10年內(nèi)最具統(tǒng)治力的語(yǔ)言,也即是替代Java霸主地位,至于未來(lái)是否可以靜待結(jié)果。至少?gòu)哪壳皣?guó)內(nèi)大廠阿里、騰訊、百度、字節(jié)的使用趨勢(shì)極其效應(yīng)可以看到其迅速擴(kuò)張的可能,越受開(kāi)發(fā)者喜愛(ài)其生態(tài)完整就會(huì)越好,如果從事企業(yè)級(jí)開(kāi)發(fā)的伙伴有時(shí)間精力建議的話不煩可以開(kāi)始深入學(xué)學(xué)Go語(yǔ)言開(kāi)發(fā)。

使用場(chǎng)景

  • 云上和網(wǎng)絡(luò)的應(yīng)用:如云計(jì)算領(lǐng)域、區(qū)塊鏈、并發(fā)網(wǎng)絡(luò)編程,有主要的云提供商強(qiáng)大的工具和api生態(tài)系統(tǒng),用Go構(gòu)建服務(wù)很容易。下面列舉小部分流行包:
    • cloud.google.com/go
    • aws/client
    • Azure/azure-sdk-for-go
  • Cli命令行接口:cli是純文本的。云和基礎(chǔ)設(shè)施應(yīng)用程序主要基于cli,這樣易于自動(dòng)化和遠(yuǎn)程功能。使用流行的開(kāi)放源碼包和健壯的標(biāo)準(zhǔn)庫(kù),可以使用Go創(chuàng)建快速而優(yōu)雅的cli。下面列舉小部分流行包:
    • spf13/cobra
    • spf13/viper
    • urfave/cli
    • delve
    • chzyer/readline
  • Web開(kāi)發(fā):Go支持快速和可擴(kuò)展的web應(yīng)用程序。下面列舉小部分流行包:
    • net/http
    • html/template
    • flosch/pongo2
    • database/sql
    • elastic/go-elasticsearch
  • 開(kāi)發(fā)運(yùn)營(yíng)和網(wǎng)站可靠性工程(云原生運(yùn)維方向,特別是基于k8s的運(yùn)維開(kāi)發(fā)):Go擁有快速的構(gòu)建時(shí)間、簡(jiǎn)潔的語(yǔ)法、自動(dòng)格式化器和文檔生成器,可以同時(shí)支持DevOps和SRE。下面列舉小部分流行包:
    • open-telemetry/opentelemetry-go
    • istio/istio
    • urfave/cli

Go 安全

Go語(yǔ)言編寫安全可靠的軟件,主要有如下信息:

  • Go安全策略:解釋了如何向Go團(tuán)隊(duì)報(bào)告Go標(biāo)準(zhǔn)庫(kù)和子庫(kù)中的安全問(wèn)題。
  • Go安全發(fā)布:Go版本歷史包含了過(guò)去安全問(wèn)題的發(fā)布說(shuō)明。根據(jù)發(fā)布策略發(fā)布了兩個(gè)最新的Go主要版本的安全補(bǔ)丁。
  • Go漏洞管理:支持幫助開(kāi)發(fā)人員找到可能影響其Go項(xiàng)目的已知公共漏洞。
  • Go Fuzzing:提供一種自動(dòng)測(cè)試,持續(xù)地操作程序的輸入以發(fā)現(xiàn)錯(cuò)誤。
  • Go加密:Go加密庫(kù)是Go標(biāo)準(zhǔn)庫(kù)和子庫(kù)中的crypto/…和golang.org/x/crypto/…包,并遵循這些原則開(kāi)發(fā)。

使用須知

搜索工具

Go 開(kāi)發(fā)包搜索網(wǎng)站 https://pkg.go.dev/

先安裝最新版本的Go。有關(guān)下載和安裝Go編譯器、工具和庫(kù)的說(shuō)明,請(qǐng)自行查找安裝文檔,版本下載(1.20.3),https://golang.google.cn/dl/

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

由于之前使用1.20.2安裝,安裝后查看版本

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

開(kāi)發(fā)過(guò)程有需要了解相當(dāng)包的使用,可以在Go開(kāi)發(fā)官網(wǎng)上查詢,這也是一個(gè)良好學(xué)習(xí)和使用方式。

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

IDE集成開(kāi)發(fā)工具可以選擇JetBrains的GoLand,一個(gè)擴(kuò)展支持JavaScript, TypeScript和數(shù)據(jù)庫(kù)的Go IDE,JetBrains Go地址

Go基礎(chǔ)命令

# 通過(guò)命令行輸入go可以查看支持命令
go
go help build

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

  • go bug:打開(kāi)Bug報(bào)告。
  • go build:用于編譯指定的源碼文件或代碼包以及它們的依賴包。常用
  • go clean:移除當(dāng)前源碼包和關(guān)聯(lián)源碼包里面編譯生成的文件,即刪除掉執(zhí)行其它命令時(shí)產(chǎn)生的一些文件和目錄,go 命令會(huì)在臨時(shí)目錄中構(gòu)建對(duì)象,因此 go clean 主要關(guān)注其他工具或手動(dòng)調(diào)用 go build 留下的對(duì)象文件。常用
  • go doc:打印與由其參數(shù)(包、const、func、類型、var、方法或結(jié)構(gòu)字段)標(biāo)識(shí)的項(xiàng)目相關(guān)聯(lián)的文檔注釋。
  • go env:打印Go語(yǔ)言的環(huán)境信息。
  • go fix:把指定代碼包的所有Go語(yǔ)言源碼文件中的舊版本代碼修正為新版本的代碼。
  • go fmt:go程序格式化,自動(dòng)對(duì)齊、空格等。如果用了IDE這個(gè)命令就不需要了。
  • go generate:?成由現(xiàn)有?件中的指令描述的運(yùn)?命令。這些命令可以運(yùn)?任何進(jìn)程,但?的是創(chuàng)建或更新 Go 源文件。
  • go get:根據(jù)要求和實(shí)際情況從互聯(lián)網(wǎng)上下載或更新指定的代碼包及其依賴包,并對(duì)它們進(jìn)行編譯和安裝。常用
  • go install:用于編譯并安裝指定的代碼包及它們的依賴包。常用
  • go list:列出指定的代碼包的信息。
  • go mod
    • go mod init:生成go.mod文件。常用
    • go mod download :下載go.mod文件中指明的所有依賴。
    • go mod tidy:整理現(xiàn)有的依賴。常用
    • go mod graph:查看現(xiàn)有的依賴結(jié)構(gòu)。
    • go mod edit:編輯go.mod文件。
    • go mod vendor :導(dǎo)出項(xiàng)目所有的依賴到vendor目錄。
    • go mod verify:校驗(yàn)一個(gè)模塊是否被篡改過(guò)。
    • go mod why:查看為什么需要依賴某模塊。
  • go work:跨文件目錄操作本地包、多個(gè)mod模塊包調(diào)用、本地測(cè)試。
  • go run:可以編譯并運(yùn)行命令源碼文件,并把編譯后的可執(zhí)行文件存放到臨時(shí)工作目錄。常用
  • go test:用于以代碼包為單位對(duì)Go語(yǔ)言編寫的程序進(jìn)行測(cè)試。常用
  • go tool:執(zhí)行g(shù)o自帶的工具。go tool pprof對(duì)cpu、內(nèi)存和協(xié)程進(jìn)行監(jiān)控;go tool trace跟蹤協(xié)程的執(zhí)行過(guò)程。
  • go version:打印 Go 可執(zhí)??件的構(gòu)建信息。
  • go vet:用于檢查Go語(yǔ)言源碼中靜態(tài)錯(cuò)誤的簡(jiǎn)單工具。

標(biāo)準(zhǔn)庫(kù)

Go 標(biāo)準(zhǔn)庫(kù) https://golang.google.cn/pkg/

精心策劃的Go項(xiàng)目列表 https://github.com/golang/go/wiki/Projects

目前官方提供190多種標(biāo)準(zhǔn)庫(kù)包(包括cmd包),涵蓋大部分的使用場(chǎng)景,如壓縮、加密、數(shù)據(jù)庫(kù)、編碼、異常、畫圖、打印、IO操作、網(wǎng)絡(luò)、操作系統(tǒng)、反射HTML模版等,可以先大概看下官方每個(gè)包功能大體說(shuō)明,需要使用某些功能細(xì)節(jié)時(shí)再具體查看官網(wǎng)。相對(duì)于標(biāo)準(zhǔn)庫(kù),其他包也稱為子庫(kù),這些包也是Go項(xiàng)目的一部分,但在Go主干之外。它們是在比Go內(nèi)核更寬松的兼容性要求下開(kāi)發(fā)的。可以用“go get”安裝它們。

基礎(chǔ)語(yǔ)法

Effective Go 概覽

Go是一門新語(yǔ)言,盡管它借鑒了現(xiàn)有語(yǔ)言的思想,但它具有不同尋常的特性,使有效的Go程序與用其相關(guān)語(yǔ)言編寫的程序在性質(zhì)上有所不同。直接將c++或Java程序翻譯成Go不太可能產(chǎn)生令人滿意的結(jié)果。重要的是要先了解它的性質(zhì)和習(xí)慣用法,了解用Go編程的既定約定比如命名、格式、程序結(jié)構(gòu)等等。比如拿分號(hào)(Semicolons)來(lái)說(shuō),像C一樣,Go的形式語(yǔ)法使用分號(hào)來(lái)終止語(yǔ)句,但與C不同的是,這些分號(hào)不會(huì)出現(xiàn)在源代碼中。相反,詞法分析器使用一個(gè)簡(jiǎn)單的規(guī)則在掃描時(shí)自動(dòng)插入分號(hào),因此輸入文本基本上沒(méi)有分號(hào),也即是在Go語(yǔ)言中不需要采用分號(hào)結(jié)尾。

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

命名規(guī)范

Go語(yǔ)言核心宗旨就是簡(jiǎn)潔,在Go語(yǔ)言的相關(guān)命名也是推薦如此,命名規(guī)則涉及變量、常量、全局函數(shù)、結(jié)構(gòu)、接口、方法等的命名,從語(yǔ)法層面進(jìn)行了以下限定;任何需要對(duì)外暴露的名字必須以大寫字母開(kāi)頭類似public,不需要對(duì)外暴露的則應(yīng)該以小寫字母開(kāi)頭類似private。

  • 一般命名:推薦駝峰命名方式,如userManger或UserManager;單詞縮寫默認(rèn)全大寫或全小寫,如userID、baiduCDN、id、cdn。
  • 項(xiàng)目名:小寫,多個(gè)單詞建議采用中劃線分隔,比如github.com/gin-gonic。
  • 包名:package的名字和目錄保持一致,盡量采取有意義的包名,簡(jiǎn)短,有意義,盡量和標(biāo)準(zhǔn)庫(kù)不要沖突。包名應(yīng)該為小寫單詞,不要使用下劃線或者混合大小寫,統(tǒng)一使用單數(shù)形式。如domain、main。
  • 文件名:文件命名一律采用小寫,見(jiàn)名思義,測(cè)試文件以test.go結(jié)尾,如stringutil.go, stringutil_test.go。
  • Local變量:保持簡(jiǎn)短;如索引采用i而不采用index,reader簡(jiǎn)寫r,buffer簡(jiǎn)寫為b;避免冗余,命名不要和上下文重疊,在方法體內(nèi)變量名count 會(huì)比runeCount更簡(jiǎn)潔,在map的上下文下可以簡(jiǎn)寫:v,ok=m[k]。
func RuneCount(b []byte) int {
    count := 0
    for i := 0; i < len(b); {
        if b[i] < RuneSelf {
            i++
        } else {
            _, n := DecodeRune(b[i:])
            i += n
        }
        count++
    }
    return count
}
func Read(b *Buffer, p []byte) (n int, err error) {
        if b.empty() {
                b.Reset()
        }
        n = copy(p, b.buf[b.off:])
        b.off += n
        return n, nil
}
  • 結(jié)構(gòu)體:名詞或名詞短語(yǔ),如Account、Book,避免使用Manager這樣的。 如果該數(shù)據(jù)結(jié)構(gòu)需要序列化,如json, 則首字母大寫, 包括里面的字段。
type Host struct {
    Port string `json:"port"`
    Address string `json:"address"`
}
  • 接口:接口單個(gè)函數(shù)的接口名以 er 為后綴,兩個(gè)函數(shù)的接口名可以綜合兩個(gè)函數(shù)名,三個(gè)以上函數(shù)的接口名類似于結(jié)構(gòu)體名。
type Reader interface {
    Read(p []byte) (n int, err error)
}
type WriteFlusher interface {
    Write([]byte) (int, error)
    Flush() error
}
type Car interface {
    Start() 
    Stop()
    Drive()
}
  • 方法:動(dòng)詞或動(dòng)詞短語(yǔ);如果是結(jié)構(gòu)體方法,那么 Receiver 的名稱應(yīng)該縮寫, 要么都使用值, 要么都用指針;一般用一個(gè)或兩個(gè)字母(優(yōu)先r);對(duì)于Receiver命名應(yīng)該統(tǒng)一, 要么都使用值, 要么都用指針,如果 Receiver 是指針可統(tǒng)一使用p。
func (b *Buffer) Read(p []byte) (n int, err error){
}
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request){
}
func (r Rectangle) Size() Point{
}
func (f foo) method() {
}
func (p *foo) method() {
}

Go沒(méi)對(duì)get/set方法特別支持,必要的時(shí)候可以自己定義,Go對(duì)get有不同建議,如

// 推薦
p.FirstName()
// 不推薦
p.GetFirstName()
  • error:自定義error命名通常以 “名稱+Error” 作為結(jié)構(gòu)體的名字,變量時(shí)會(huì)用簡(jiǎn)寫err + 名稱。
type TypeError struct {
	Errors []string
}
ErrShortDst = errors.New("transform: short destination buffer")
  • 常用縮寫
src = source
srv = server
arg = argument
conn = connect, connection
attr = attribute
abs = absolute
min = minimum
len = length
auth = authenticate
buf = buffer
ctl = control
ctx = context
str = string
msg = message
fmt = format
dest = destination
diff = difference
orig = original
recv = receive
ref = reference
repo = repository
util = utility

注釋

Go提供C風(fēng)格的/* */塊注釋和c++風(fēng)格的//行注釋。行注釋是常態(tài);塊注釋主要作為包注釋出現(xiàn),但在表達(dá)式中或禁用大量代碼時(shí)很有用。

變量

在Go語(yǔ)言中,變量被顯式聲明并被編譯器用來(lái)檢查函數(shù)調(diào)用的類型正確性;var聲明1個(gè)或多個(gè)變量。

package main

import "fmt"

func main() {

    var a = "initial"
    fmt.Println(a)

    var b, c int = 1, 2
    fmt.Println(b, c)

    var d = true
    fmt.Println(d)

    var e int
    fmt.Println(e)

    f := "apple"
    fmt.Println(f)
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

常量(const)

Go支持字符常量、字符串常量、布爾常量和數(shù)值常量;const聲明一個(gè)常數(shù)值。

package main
import (
    "fmt"
    "math"
)
const s string = "constant"
func main() {
    fmt.Println(s)
    const n = 500000000
    const d = 3e20 / n
    fmt.Println(d)
    fmt.Println(int64(d))
    fmt.Println(math.Sin(n))
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

控制結(jié)構(gòu)

  • 循環(huán)(For):for是Go唯一的循環(huán)結(jié)構(gòu)。
package main

import "fmt"

func main() {

    i := 1
    for i <= 3 {
        fmt.Println(i)
        i = i + 1
    }

    for j := 7; j <= 9; j++ {
        fmt.Println(j)
    }

    for {
        fmt.Println("loop")
        break
    }

    for n := 0; n <= 5; n++ {
        if n%2 == 0 {
            continue
        }
        fmt.Println(n)
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

  • 選擇(If/Else):在Go中沒(méi)有三元if,所以即使對(duì)于基本條件,也需要使用完整的if語(yǔ)句。
package main

import "fmt"

func main() {

    if 7%2 == 0 {
        fmt.Println("7 is even")
    } else {
        fmt.Println("7 is odd")
    }

    if 8%4 == 0 {
        fmt.Println("8 is divisible by 4")
    }

    if num := 9; num < 0 {
        fmt.Println(num, "is negative")
    } else if num < 10 {
        fmt.Println(num, "has 1 digit")
    } else {
        fmt.Println(num, "has multiple digits")
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

  • Switch:跨多個(gè)分支表達(dá)條件。
package main

import (
    "fmt"
    "time"
)

func main() {

    i := 2
    fmt.Print("Write ", i, " as ")
    switch i {
    case 1:
        fmt.Println("one")
    case 2:
        fmt.Println("two")
    case 3:
        fmt.Println("three")
    }

    switch time.Now().Weekday() {
    case time.Saturday, time.Sunday:
        fmt.Println("It's the weekend")
    default:
        fmt.Println("It's a weekday")
    }

    t := time.Now()
    switch {
    case t.Hour() < 12:
        fmt.Println("It's before noon")
    default:
        fmt.Println("It's after noon")
    }

    whatAmI := func(i interface{}) {
        switch t := i.(type) {
        case bool:
            fmt.Println("I'm a bool")
        case int:
            fmt.Println("I'm an int")
        default:
            fmt.Printf("Don't know type %T\n", t)
        }
    }
    whatAmI(true)
    whatAmI(1)
    whatAmI("hey")
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

數(shù)據(jù)類型

  • 數(shù)組(Arrays):數(shù)組是特定長(zhǎng)度的元素的編號(hào)序列。單在典型的Go代碼中,切片更為常見(jiàn),后面介紹。
package main

import "fmt"

func main() {

    var a [5]int
    fmt.Println("emp:", a)

    a[4] = 100
    fmt.Println("set:", a)
    fmt.Println("get:", a[4])

    fmt.Println("len:", len(a))

    b := [5]int{1, 2, 3, 4, 5}
    fmt.Println("dcl:", b)

    var twoD [2][3]int
    for i := 0; i < 2; i++ {
        for j := 0; j < 3; j++ {
            twoD[i][j] = i + j
        }
    }
    fmt.Println("2d: ", twoD)
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

  • 切片(Slices):是Go中的一種重要數(shù)據(jù)類型,它為序列提供了比數(shù)組更強(qiáng)大的接口。
package main

import "fmt"

func main() {

    s := make([]string, 3)
    fmt.Println("emp:", s)

    s[0] = "a"
    s[1] = "b"
    s[2] = "c"
    fmt.Println("set:", s)
    fmt.Println("get:", s[2])

    fmt.Println("len:", len(s))

    s = append(s, "d")
    s = append(s, "e", "f")
    fmt.Println("apd:", s)

    c := make([]string, len(s))
    copy(c, s)
    fmt.Println("cpy:", c)

    l := s[2:5]
    fmt.Println("sl1:", l)

    l = s[:5]
    fmt.Println("sl2:", l)

    l = s[2:]
    fmt.Println("sl3:", l)

    t := []string{"g", "h", "i"}
    fmt.Println("dcl:", t)

    twoD := make([][]int, 3)
    for i := 0; i < 3; i++ {
        innerLen := i + 1
        twoD[i] = make([]int, innerLen)
        for j := 0; j < innerLen; j++ {
            twoD[i][j] = i + j
        }
    }
    fmt.Println("2d: ", twoD)
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

  • 映射(Maps):Go內(nèi)置的關(guān)聯(lián)數(shù)據(jù)類型,在其他語(yǔ)言中有時(shí)稱為哈希或字典。
package main

import "fmt"

func main() {

    m := make(map[string]int)

    m["k1"] = 7
    m["k2"] = 13

    fmt.Println("map:", m)

    v1 := m["k1"]
    fmt.Println("v1:", v1)

    v3 := m["k3"]
    fmt.Println("v3:", v3)

    fmt.Println("len:", len(m))

    delete(m, "k2")
    fmt.Println("map:", m)

    _, prs := m["k2"]
    fmt.Println("prs:", prs)

    n := map[string]int{"foo": 1, "bar": 2}
    fmt.Println("map:", n)
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

迭代(range)

Range遍歷各種數(shù)據(jù)結(jié)構(gòu)中的元素

package main

import "fmt"

func main() {

    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    fmt.Println("sum:", sum)

    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }

    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }

    for k := range kvs {
        fmt.Println("key:", k)
    }

    for i, c := range "go" {
        fmt.Println(i, c)
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

函數(shù)

Go函數(shù)返回值需要顯式返回,即它不會(huì)自動(dòng)返回最后一個(gè)表達(dá)式的值。有多個(gè)相同類型的連續(xù)參數(shù)時(shí)可以省略類型相似的參數(shù)的類型名稱,直到聲明該類型的最后一個(gè)參數(shù)。

package main

import "fmt"

// 多個(gè)參數(shù)
func plus(a int, b int) int {

	return a + b
}
// 多個(gè)相同類型參數(shù)
func plusPlus(a, b, c int) int {
	return a + b + c
}
// 多個(gè)返回值
func vals() (int, int) {
	return 3, 7
}
// 可變參數(shù)
func sum(nums ...int) {
    fmt.Print(nums, " ")
    total := 0

    for _, num := range nums {
        total += num
    }
    fmt.Println(total)
}
// 閉包,Go支持匿名函數(shù),它可以形成閉包。當(dāng)想要內(nèi)聯(lián)定義一個(gè)函數(shù)而不必命名它時(shí)可以使用匿名函數(shù)很。
func intSeq() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}
// 遞歸函數(shù)
func fact(n int) int {
    if n == 0 {
        return 1
    }
    return n * fact(n-1)
}

func main() {

	res := plus(1, 2)
	fmt.Println("1+2 =", res)

	res = plusPlus(1, 2, 3)
	fmt.Println("1+2+3 =", res)
    
    a, b := vals()
	fmt.Println(a)
	fmt.Println(b)

	_, c := vals()
	fmt.Println(c)
    
    sum(1, 2)
    sum(1, 2, 3)

    nums := []int{1, 2, 3, 4}
    sum(nums...)
    
    nextInt := intSeq()

    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())

    newInts := intSeq()
    fmt.Println(newInts())
    
    fmt.Println(fact(7))

    var fib func(n int) int

    fib = func(n int) int {
        if n < 2 {
            return n
        }

        return fib(n-1) + fib(n-2)
    }

    fmt.Println(fib(7))
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

指針

Go支持指針,允許在程序中傳遞對(duì)值和記錄的引用。

package main

import "fmt"

func zeroval(ival int) {
    ival = 0
}

func zeroptr(iptr *int) {
    *iptr = 0
}

func main() {
    i := 1
    fmt.Println("initial:", i)

    zeroval(i)
    fmt.Println("zeroval:", i)

    zeroptr(&i)
    fmt.Println("zeroptr:", i)

    fmt.Println("pointer:", &i)
}

字符串和符文

Go字符串是字節(jié)的只讀切片。該語(yǔ)言和標(biāo)準(zhǔn)庫(kù)將字符串特殊地視為UTF-8編碼文本的容器。在其他語(yǔ)言中,字符串是由“字符”組成的。在go中,字符的概念被稱為符文——它是一個(gè)表示Unicode碼點(diǎn)的整數(shù)。

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {

    const s = "??????"

    fmt.Println("Len:", len(s))

    for i := 0; i < len(s); i++ {
        fmt.Printf("%x ", s[i])
    }
    fmt.Println()

    fmt.Println("Rune count:", utf8.RuneCountInString(s))

    for idx, runeValue := range s {
        fmt.Printf("%#U starts at %d\n", runeValue, idx)
    }

    fmt.Println("\nUsing DecodeRuneInString")
    for i, w := 0, 0; i < len(s); i += w {
        runeValue, width := utf8.DecodeRuneInString(s[i:])
        fmt.Printf("%#U starts at %d\n", runeValue, i)
        w = width

        examineRune(runeValue)
    }
}

func examineRune(r rune) {

    if r == 't' {
        fmt.Println("found tee")
    } else if r == '?' {
        fmt.Println("found so sua")
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

結(jié)構(gòu)體(struct)

Go的結(jié)構(gòu)體是字段的類型化集合,將數(shù)據(jù)分組形成記錄;結(jié)構(gòu)體是可變的。

package main

import "fmt"

type person struct {
    name string
    age  int
}

func newPerson(name string) *person {

    p := person{name: name}
    p.age = 42
    return &p
}

func main() {

    fmt.Println(person{"Bob", 20})

    fmt.Println(person{name: "Alice", age: 30})

    fmt.Println(person{name: "Fred"})

    fmt.Println(&person{name: "Ann", age: 40})

    fmt.Println(newPerson("Jon"))

    s := person{name: "Sean", age: 50}
    fmt.Println(s.name)

    sp := &s
    fmt.Println(sp.age)

    sp.age = 51
    fmt.Println(sp.age)
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

方法

Go支持在結(jié)構(gòu)類型上定義的方法。方法的接受者可以是結(jié)構(gòu)體也可以是指向結(jié)構(gòu)體的指針。

package main

import "fmt"

type rect struct {
	width, height int
}

func (r *rect) area() int {
	return r.width * r.height
}

func (r rect) perim() int {
	return 2*r.width + 2*r.height
}

func main() {
	r := rect{width: 10, height: 5}

	fmt.Println("area: ", r.area())
	fmt.Println("perim:", r.perim())

	rp := &r
	fmt.Println("area: ", rp.area())
	fmt.Println("perim:", rp.perim())
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

接口(interface)

接口是方法簽名的命名集合。

package main

import (
    "fmt"
    "math"
)

type geometry interface {
    area() float64
    perim() float64
}

type rect struct {
    width, height float64
}
type circle struct {
    radius float64
}

func (r rect) area() float64 {
    return r.width * r.height
}
func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}

func measure(g geometry) {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
}

func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}

    measure(r)
    measure(c)
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

Go支持嵌入結(jié)構(gòu)體和接口,以表達(dá)更豐富的類型組合。

package main

import "fmt"

type base struct {
    num int
}

func (b base) describe() string {
    return fmt.Sprintf("base with num=%v", b.num)
}

type container struct {
    base
    str string
}

func main() {

    co := container{
        base: base{
            num: 1,
        },
        str: "some name",
    }

    fmt.Printf("co={num: %v, str: %v}\n", co.num, co.str)

    fmt.Println("also num:", co.base.num)

    fmt.Println("describe:", co.describe())

    type describer interface {
        describe() string
    }

    var d describer = co
    fmt.Println("describer:", d.describe())
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

泛型

Go 1.18 引入了泛型,為 Go 語(yǔ)言帶來(lái)了更強(qiáng)大的類型系統(tǒng),使其可以更好地支持各種數(shù)據(jù)類型和算法。Go 泛型可以應(yīng)用于各種數(shù)據(jù)類型和算法,使代碼更加通用、簡(jiǎn)潔、易讀和易維護(hù)。

package main

import "fmt"

func MapKeys[K comparable, V any](m map[K]V) []K {
    r := make([]K, 0, len(m))
    for k := range m {
        r = append(r, k)
    }
    return r
}

type List[T any] struct {
    head, tail *element[T]
}

type element[T any] struct {
    next *element[T]
    val  T
}

func (lst *List[T]) Push(v T) {
    if lst.tail == nil {
        lst.head = &element[T]{val: v}
        lst.tail = lst.head
    } else {
        lst.tail.next = &element[T]{val: v}
        lst.tail = lst.tail.next
    }
}

func (lst *List[T]) GetAll() []T {
    var elems []T
    for e := lst.head; e != nil; e = e.next {
        elems = append(elems, e.val)
    }
    return elems
}

func main() {
    var m = map[int]string{1: "2", 2: "4", 4: "8"}

    fmt.Println("keys:", MapKeys(m))

    _ = MapKeys[int, string](m)

    lst := List[int]{}
    lst.Push(10)
    lst.Push(13)
    lst.Push(23)
    fmt.Println("list:", lst.GetAll())
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

以下是一些使用 Go 泛型的場(chǎng)景:

  • 集合數(shù)據(jù)類型:Go 泛型可以方便地定義各種集合數(shù)據(jù)類型,如棧、隊(duì)列、鏈表、二叉樹(shù)等。下面使用泛型定義棧的例子定義了一個(gè) Stack[T] 類型,表示一個(gè)可以存儲(chǔ)任意類型 T 的棧。Push 方法用于將一個(gè)元素壓入棧中,Pop 方法用于彈出棧頂?shù)脑亍?/li>
  • 算法實(shí)現(xiàn):泛型還可以用于實(shí)現(xiàn)各種算法,如排序、查找、字符串匹配等。以下是一個(gè)使用泛型實(shí)現(xiàn)快速排序的例子:在這個(gè)例子中,使用泛型定義 QuickSort 函數(shù),可以對(duì)任意類型 T 的切片進(jìn)行排序。該函數(shù)采用經(jīng)典的快速排序算法實(shí)現(xiàn)。

錯(cuò)誤(errors)

在Go中,習(xí)慣上通過(guò)顯式的單獨(dú)返回值來(lái)傳達(dá)錯(cuò)誤。這與Java和Ruby等語(yǔ)言中使用的異常以及c中有時(shí)使用的重載的單個(gè)結(jié)果/錯(cuò)誤值形成對(duì)比。Go的方法可以很容易地看到哪些函數(shù)返回錯(cuò)誤,并使用用于任何其他無(wú)錯(cuò)誤任務(wù)的相同語(yǔ)言結(jié)構(gòu)來(lái)處理它們。

package main

import (
    "errors"
    "fmt"
)

func f1(arg int) (int, error) {
    if arg == 42 {

        return -1, errors.New("can't work with 42")

    }

    return arg + 3, nil
}

type argError struct {
    arg  int
    prob string
}

func (e *argError) Error() string {
    return fmt.Sprintf("%d - %s", e.arg, e.prob)
}

func f2(arg int) (int, error) {
    if arg == 42 {

        return -1, &argError{arg, "can't work with it"}
    }
    return arg + 3, nil
}

func main() {

    for _, i := range []int{7, 42} {
        if r, e := f1(i); e != nil {
            fmt.Println("f1 failed:", e)
        } else {
            fmt.Println("f1 worked:", r)
        }
    }
    for _, i := range []int{7, 42} {
        if r, e := f2(i); e != nil {
            fmt.Println("f2 failed:", e)
        } else {
            fmt.Println("f2 worked:", r)
        }
    }

    _, e := f2(42)
    if ae, ok := e.(*argError); ok {
        fmt.Println(ae.arg)
        fmt.Println(ae.prob)
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

恐慌(pinic)

恐慌通常意味著事情出乎意料地出錯(cuò)了;大多數(shù)情況下,使用它來(lái)快速處理在正常操作中不應(yīng)該發(fā)生的錯(cuò)誤,或者沒(méi)有準(zhǔn)備好優(yōu)雅地處理的錯(cuò)誤。

package main

import "os"

func main() {

    panic("a problem")

    _, err := os.Create("/tmp/file")
    if err != nil {
        panic(err)
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

推遲(defer)

Defer用于確保函數(shù)調(diào)用在程序執(zhí)行的后期執(zhí)行,通常是出于清理目的。Defer通常用于其他語(yǔ)言中使用的地方,例如ensure和finally。比如用于釋放或關(guān)閉連接、釋放或關(guān)閉文件句柄等

package main

import (
    "fmt"
    "os"
)

func main() {

    f := createFile("d:/tmp/defer.txt")
    defer closeFile(f)
    writeFile(f)
}

func createFile(p string) *os.File {
    fmt.Println("creating")
    f, err := os.Create(p)
    if err != nil {
        panic(err)
    }
    return f
}

func writeFile(f *os.File) {
    fmt.Println("writing")
    fmt.Fprintln(f, "data")

}

func closeFile(f *os.File) {
    fmt.Println("closing")
    err := f.Close()

    if err != nil {
        fmt.Fprintf(os.Stderr, "error: %v\n", err)
        os.Exit(1)
    }
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)

恢復(fù)(recover)

通過(guò)使用內(nèi)置的recover函數(shù),Go使從恐慌中恢復(fù)成為可能?;謴?fù)可以阻止因恐慌而中止程序,而是讓程序繼續(xù)執(zhí)行。

package main

import "fmt"

func mayPanic() {
    panic("a problem")
}

func main() {

    defer func() {
        if r := recover(); r != nil {

            fmt.Println("Recovered. Error:\n", r)
        }
    }()

    mayPanic()

    fmt.Println("After mayPanic()")
}

云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-428518.html

  • 本人博客網(wǎng)站IT小神 www.itxiaoshen.com

到了這里,關(guān)于云原生時(shí)代崛起的編程語(yǔ)言Go基礎(chǔ)實(shí)戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Go】四、rpc跨語(yǔ)言編程基礎(chǔ)與rpc的調(diào)用基礎(chǔ)原理

    早期 Go 語(yǔ)言不使用 go module 進(jìn)行包管理,而是使用 go path 進(jìn)行包管理,這種管理方式十分老舊,兩者最顯著的區(qū)別就是:Go Path 創(chuàng)建之后沒(méi)有 go.mod 文件被創(chuàng)建出來(lái),而 go module 模式會(huì)創(chuàng)建出一個(gè) go.mod 文件用于管理包信息 現(xiàn)在就是:盡量使用 Go Modules 模式 另外,我們?cè)谝氚?/p>

    2024年02月19日
    瀏覽(23)
  • 【Go 基礎(chǔ)篇】Go語(yǔ)言關(guān)鍵字和預(yù)定義標(biāo)識(shí)符解析:探索編程的基石與核心要素

    在計(jì)算機(jī)編程中,(Keywords)和預(yù)定義標(biāo)識(shí)符(Predefined Identifiers)是編程語(yǔ)言的核心要素,它們?cè)谡Z(yǔ)法結(jié)構(gòu)和語(yǔ)言功能中起到重要作用。在Go語(yǔ)言(Golang)中,和預(yù)定義標(biāo)識(shí)符定義了編程的基本規(guī)則和構(gòu)建塊,是實(shí)現(xiàn)功能的關(guān)鍵。本篇博客將深入探討Go語(yǔ)言中的關(guān)

    2024年02月12日
    瀏覽(131)
  • 100天精通Golang(基礎(chǔ)入門篇)——第15天:深入解析Go語(yǔ)言中函數(shù)的應(yīng)用:從基礎(chǔ)到進(jìn)階,助您精通函數(shù)編程!(進(jìn)階)

    100天精通Golang(基礎(chǔ)入門篇)——第15天:深入解析Go語(yǔ)言中函數(shù)的應(yīng)用:從基礎(chǔ)到進(jìn)階,助您精通函數(shù)編程?。ㄟM(jìn)階)

    ?? 博主 libin9iOak帶您 Go to Golang Language.? ?? 個(gè)人主頁(yè)——libin9iOak的博客?? ?? 《面試題大全》 文章圖文并茂??生動(dòng)形象??簡(jiǎn)單易學(xué)!歡迎大家來(lái)踩踩~?? ?? 《IDEA開(kāi)發(fā)秘籍》學(xué)會(huì)IDEA常用操作,工作效率翻倍~?? ?? 希望本文能夠給您帶來(lái)一定的幫助??文章粗淺,敬請(qǐng)批

    2024年02月12日
    瀏覽(36)
  • GO編程語(yǔ)言:簡(jiǎn)潔、高效、強(qiáng)大的開(kāi)源編程語(yǔ)言

    GO編程語(yǔ)言:簡(jiǎn)潔、高效、強(qiáng)大的開(kāi)源編程語(yǔ)言

    在現(xiàn)代軟件開(kāi)發(fā)領(lǐng)域,隨著應(yīng)用復(fù)雜度的不斷提升,開(kāi)發(fā)人員對(duì)編程語(yǔ)言的需求也日益增長(zhǎng)。GO編程語(yǔ)言,作為一種簡(jiǎn)潔、高效且具備強(qiáng)大并發(fā)能力的新型開(kāi)源編程語(yǔ)言,逐漸成為了許多開(kāi)發(fā)者的首選。本文將詳細(xì)介紹GO語(yǔ)言在哪些項(xiàng)目開(kāi)發(fā)中表現(xiàn)出色,以及為什么許多開(kāi)發(fā)者

    2024年02月02日
    瀏覽(174)
  • Go語(yǔ)言網(wǎng)絡(luò)編程(socket編程)WebSocket編程

    WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議 WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡(jiǎn)單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù) 在WebSocket API中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸 需要安裝第

    2024年02月09日
    瀏覽(93)
  • Go語(yǔ)言網(wǎng)絡(luò)編程(socket編程)http編程

    Web服務(wù)器的工作原理可以簡(jiǎn)單地歸納為 客戶機(jī)通過(guò)TCP/IP協(xié)議建立到服務(wù)器的TCP連接 客戶端向服務(wù)器發(fā)送HTTP協(xié)議請(qǐng)求包,請(qǐng)求服務(wù)器里的資源文檔 服務(wù)器向客戶機(jī)發(fā)送HTTP協(xié)議應(yīng)答包,如果請(qǐng)求的資源包含有動(dòng)態(tài)語(yǔ)言的內(nèi)容,那么服務(wù)器會(huì)調(diào)用動(dòng)態(tài)語(yǔ)言的解釋引擎負(fù)責(zé)處理“

    2024年02月09日
    瀏覽(95)
  • GO語(yǔ)言網(wǎng)絡(luò)編程(并發(fā)編程)Channel

    GO語(yǔ)言網(wǎng)絡(luò)編程(并發(fā)編程)Channel

    1.1.1 Channel 單純地將函數(shù)并發(fā)執(zhí)行是沒(méi)有意義的。函數(shù)與函數(shù)間需要交換數(shù)據(jù)才能體現(xiàn)并發(fā)執(zhí)行函數(shù)的意義。 雖然可以使用共享內(nèi)存進(jìn)行數(shù)據(jù)交換,但是共享內(nèi)存在不同的goroutine中容易發(fā)生競(jìng)態(tài)問(wèn)題。為了保證數(shù)據(jù)交換的正確性,必須使用互斥量對(duì)內(nèi)存進(jìn)行加鎖,這種做法勢(shì)

    2024年02月09日
    瀏覽(105)
  • GO語(yǔ)言網(wǎng)絡(luò)編程(并發(fā)編程)select

    1.1.1 select多路復(fù)用 在某些場(chǎng)景下我們需要同時(shí)從多個(gè)通道接收數(shù)據(jù)。通道在接收數(shù)據(jù)時(shí),如果沒(méi)有數(shù)據(jù)可以接收將會(huì)發(fā)生阻塞。你也許會(huì)寫出如下代碼使用遍歷的方式來(lái)實(shí)現(xiàn): 這種方式雖然可以實(shí)現(xiàn)從多個(gè)通道接收值的需求,但是運(yùn)行性能會(huì)差很多。為了應(yīng)對(duì)這種場(chǎng)景,G

    2024年02月09日
    瀏覽(240)
  • 【Go編程語(yǔ)言】流程控制

    【Go編程語(yǔ)言】流程控制

    程序的流程控制結(jié)構(gòu)一具有三種:順序結(jié)構(gòu),選擇結(jié)構(gòu),循環(huán)結(jié)構(gòu) 順序結(jié)構(gòu):從上到下,逐行執(zhí)行。默認(rèn)的邏輯 選擇結(jié)構(gòu):條件滿足某些代碼才會(huì)執(zhí)行 if switch select ,后面 channel 再講 循環(huán)結(jié)構(gòu):條件滿足某些代碼會(huì)被反復(fù)執(zhí)行0-N次 for 條件語(yǔ)句需要開(kāi)發(fā)者通過(guò)指定一個(gè)或多個(gè)條

    2024年02月06日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包