<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一通百通,Go語言入門如此輕松

          共 11290字,需瀏覽 23分鐘

           ·

          2024-03-23 14:00

          Part1 前言

          沒有最完美的語言,只有最完美的使用場景。

          不同語言在不同業(yè)務(wù)場景下發(fā)揮著不同的作用。

          初期掌握一門編程語言,也能夠在IT 行業(yè)中游刃有余,然而,隨著在軟件開發(fā)中的經(jīng)驗積累,你可能會發(fā)現(xiàn)一門語言的局限性。不同的編程語言在不同的業(yè)務(wù)場景下發(fā)揮著不同的作用。有些語言更適合構(gòu)建大規(guī)模分布式系統(tǒng),有些語言更適合處理高并發(fā)的網(wǎng)絡(luò)請求,而有些語言則更適合開發(fā)移動應(yīng)用程序或數(shù)據(jù)科學(xué)領(lǐng)域。

          然而編程的基本概念,如變量、數(shù)據(jù)類型、條件語句、循環(huán)和函數(shù)等。在大多數(shù)編程語言中都是通用的,并且可以通過類比和遷移的方式應(yīng)用于其他語言。

          編程語言之間往往存在某種程度的相似性。那么本文就以這些內(nèi)容為出發(fā)點作為Go語言的敲門磚。

          Part2 學(xué)習(xí)范圍 8b8ee800128b88a86f6a682249c86c43.webp Part3 正文

          調(diào)試步驟:有條件的可以在本機上安裝 go 環(huán)境,懶得折騰的可以直接利用網(wǎng)頁版開發(fā)環(huán)境:Go.Dev

          1 一)Hello World

          作為學(xué)習(xí)的必經(jīng)之路,我們很有必要了解一下Go語言中如何實現(xiàn) hello word 程序

                
                package main    // Go程序的包聲明。Go程序由多個包組成

          import "fmt"    // fmt包,它提供了格式化輸入和輸出的功能

          func main() {   // 程序的主函數(shù),也是程序的入口點
           fmt.Println("hello world")
          }

          2 二)變量和數(shù)據(jù)類型

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

          定義變量之前我們需要先了解在Go語言中提供了幾種基本數(shù)據(jù)類型:

          1. 布爾類型

          bool,表示邏輯值,只有兩個取值:truefalse

          2. 數(shù)字類型

          支持整型(int)和浮點型(float)數(shù)字,并且支持復(fù)數(shù)(complex)。

          3. 字符串類型

          string,表示一串字符序列。是由單個字節(jié)連接起來的。Go 語言的字符串的字節(jié)使用 UTF-8 編碼標(biāo)識 Unicode 文本。

          4. 派生類型

          • 指針類型(Pointer Types):用于存儲變量的內(nèi)存地址。
          • 數(shù)組類型(Array Types):表示固定長度的同一類型元素的集合。
          • 結(jié)構(gòu)體類型(Struct Types):表示具有不同類型字段的自定義數(shù)據(jù)結(jié)構(gòu)。
          • 通道類型(Channel Types):用于在Go協(xié)程之間進行通信。
          • 切片類型(Slice Types):表示可變長度的元素序列。
          • 映射類型(Map Types):表示鍵-值對的集合。
          • 錯誤類型(Error Type)error,表示錯誤的接口類型。

          這么多類型記不住?沒關(guān)系,用到的時候自然就記住了

          2、變量與常量

          1)單變量聲明

          在 Go 中,有兩種方式可以聲明變量

          • 使用 var 關(guān)鍵字
                
                var variablename [type] = value

          看到這個有點意思,通過 var 可以想到 JavaScript,通過 variablename type 的類型聲明又可以聯(lián)想到 TypeScript,不同的是少了 :

          • 使用 := 標(biāo)識符
                
                variablename := value

          在這種情況下,變量的類型是從值推斷出來的(意味著編譯器根據(jù)值決定變量的類型)。

          示例84d2ea2e5031a46eb90d4daef30070d0.webp

          2)多變量聲明

          在 Go 中,可以在同一行中聲明多個變量。132f1e2741a1c970929950fb612b8b9a.webp

          3)常量聲明

                
                const variablename [type] = value

          關(guān)鍵字是 const,可以省略類型說明符 [type],因為編譯器可以根據(jù)變量的值來推斷其類型。

          • 顯式類型定義: const b string = "abc"
          • 隱式類型定義: const b = "abc"

          4)常量枚舉

                
                const (  
              a = "abc"  
              b = len(a)  
              c = unsafe.Sizeof(a)  
          )

          常量表達(dá)式中,函數(shù)必須是內(nèi)置函數(shù)

          3 三)控制流程語句

          1、if 語句

          基本使用如下,這邊需要注意的是 條件 不需要使用 () 包裹

                
                if condition { 
          else if condition {
          else {}
          1cbe39fb3477625631a761b6f82738ec.webp

          2、switch 語句

          使用 switch 語句來選擇要執(zhí)行的多個代碼塊之一。Go 中的語句類似于 C、C++、Java、JavaScript 和 PHP 中的 switch 語句。不同之處在于它只運行對應(yīng)匹配的代碼塊,因此不需要 break 語句。b6c626d4563cedb229514c8f0d7221cd.webp使用須知:

          • 表達(dá)式只計算一次
          • switch 將表達(dá)式的值與每個 case 表達(dá)式的值進行比較
          • 如果存在匹配項,則執(zhí)行關(guān)聯(lián)的代碼塊
          • 關(guān)鍵字 default 是可選的。它指定在沒有 case 匹配項時要運行的一些代碼

          1)多用例 switch 語句

          switch 語句 case 中可以為單個值有多個值:

                
                switch _expression_ {  
          case x, y:  
           ...do something
          case v, w:
           ...do something
          case z:  
           ...do something  
          default:
           ...do something  
          }
          ede1c70a91823a2fa5312e32431ebc20.webp

          3、for 語句

          for 循環(huán)是 Go 中唯一可用的循環(huán)。

                
                 for statement1; statement2; statement3 {  
             ...do something  
          }

          使用須知:

          • 語句 1 初始化循環(huán)計數(shù)器值。
          • 語句 2 針對每個循環(huán)迭代計算。
          • 語句3 增加循環(huán)計數(shù)器值。32306018705680b0d093049ea636b370.webp

          1)continue

          continue 語句用于跳過循環(huán)中的一次或多次迭代。然后,它繼續(xù)循環(huán)中的下一次迭代。

          2)break

          break 語句用于中斷/終止循環(huán)執(zhí)行。

          3)range 關(guān)鍵字

          關(guān)鍵字 range 用于更輕松地迭代數(shù)組、切片或映射。它同時返回索引和值。

                
                for index, value := range array|slice|map {  
           ...do something  
          }
          0963d40d5c2ab274e90289561d31f309.webp

          4 四)函數(shù)

          1、基本聲明

          什么是函數(shù)?函數(shù)是可以在程序中重復(fù)使用的語句塊。要聲明函數(shù),需要執(zhí)行以下操作:

          • 使用 func 關(guān)鍵字。
          • 指定函數(shù)的名稱,后跟括號 ()() 內(nèi)可添加參數(shù)列表
          • 最后,在大括號 {} 內(nèi)添加定義函數(shù)應(yīng)執(zhí)行的操作的代碼。
                
                func FunctionName(param1 type, param2 type, param3 type) {  
           ...do something  
          }
          c2ff1b56ede5f05e27c12e6461252689.webp

          2、多值返回

          函數(shù)中可以返回多個值

                
                func swap(x, y string) (stringstring) {  
             return y, x  
          }

          3、連續(xù)參數(shù)

          當(dāng)兩個或多個連續(xù)的命名函數(shù)參數(shù)共享一個類型時,可以省略除最后一個之外的所有類型。587e2de151f325619a674519347c1de3.webp

          5 五)數(shù)據(jù)結(jié)構(gòu)

          1、數(shù)組

          數(shù)組用于在單個變量中存儲相同類型的多個值,而不是為每個值聲明單獨的變量。

          1)創(chuàng)建方式

          1. 使用數(shù)組字面量初始化:
                
                array := [size]Type{element1, element2, ...}

          這種方式直接使用數(shù)組字面量來初始化數(shù)組,并提供初始元素。例如:

                
                numbers := [5]int{12345}
          1. 聲明數(shù)組后逐個賦值:
                
                var array [size]Type
          array[index] = value

          這種方式先聲明一個數(shù)組,然后逐個為數(shù)組元素賦值。例如:

                
                var numbers [2]int
          numbers[0] = 1
          numbers[1] = 2
          1. 使用數(shù)組初始化表達(dá)式:
                
                array := [...]Type{element1, element2, ...}

          這種方式使用 ... 來讓編譯器根據(jù)提供的初始元素數(shù)量自動推斷數(shù)組的大小。例如:

                
                numbers := [...]int{12345}

          上述代碼將根據(jù)提供的 5 個初始元素推斷出數(shù)組的大小為 5。

          需要注意的是,數(shù)組的長度在聲明后是固定的,無法更改。如果需要動態(tài)長度的序列,可以使用切片(slice)類型。

          2)常見操作

          • len():返回數(shù)組的長度,即數(shù)組中元素的個數(shù)。
          • for循環(huán):可以使用for循環(huán)和數(shù)組的長度來遍歷數(shù)組中的元素。
          • 索引訪問:通過索引操作符[]來訪問和修改數(shù)組中的元素。
          • 多維數(shù)組:Go語言支持多維數(shù)組,可以使用嵌套的方式創(chuàng)建和訪問多維數(shù)組。

          2、切片

          切片(slice)是一種動態(tài)長度的數(shù)據(jù)結(jié)構(gòu),它是對底層數(shù)組的一種引用。切片提供了一種方便且靈活的方式來操作和管理數(shù)據(jù)集合。切片由以下三個部分組成:

          1. 指針(Pointer):指向底層數(shù)組的第一個元素。
          2. 長度(Length):切片當(dāng)前包含的元素個數(shù)。
          3. 容量(Capacity):底層數(shù)組從切片的起始位置到數(shù)組末尾的元素個數(shù)。

          1)創(chuàng)建方式

          以下是幾種常見的切片創(chuàng)建方式:

          1. 使用切片字面量初始化:
                
                slice := []Type{element1, element2, ...}

          這種方式直接使用切片字面量來初始化切片,并提供初始元素。例如:

                
                numbers := []int{12345}
          1. 使用 make() 函數(shù)創(chuàng)建指定長度的切片:
                
                slice := make([]Type, length)

          這種方式使用 make() 函數(shù)創(chuàng)建指定長度的切片,初始值為該類型的零值。例如:

                
                numbers := make([]int5)

          上述代碼將創(chuàng)建一個包含 5 個整數(shù)的切片。

          1. 使用 make() 函數(shù)創(chuàng)建指定長度和容量的切片:
                
                slice := make([]Type, length, capacity)

          這種方式使用 make() 函數(shù)創(chuàng)建指定長度和容量的切片。length 表示切片的長度,capacity 表示底層數(shù)組的容量,初始值為該類型的零值。例如:

                
                numbers := make([]int510)

          上述代碼將創(chuàng)建一個長度為 5,容量為 10 的切片。

          1. 通過切片表達(dá)式(Slice Expression)從現(xiàn)有切片或數(shù)組創(chuàng)建切片:
                
                slice := existingSliceOrArray[start:end]

          這種方式使用切片表達(dá)式從現(xiàn)有的切片或數(shù)組中創(chuàng)建一個新的切片。start 表示起始索引(包含),end 表示結(jié)束索引(不包含)。例如:

                
                numbers := []int{12345}
          subSlice := numbers[1:3]

          上述代碼將從 numbers 切片中創(chuàng)建一個新的切片 subSlice,包含索引 1 到索引 2 的元素。

          2)常見操作

          切片還有一些內(nèi)置函數(shù)和操作符,可以方便地進行切片的創(chuàng)建、修改和操作,例如:

          • append():用于向切片末尾添加元素,可以動態(tài)擴展切片的長度。
          • copy():用于復(fù)制切片的內(nèi)容到另一個切片或數(shù)組。
          • len():返回切片的長度。
          • cap():返回切片的容量。

          切片是引用類型,多個切片可以共享同一個底層數(shù)組。當(dāng)對一個切片進行修改時,其他共享同一底層數(shù)組的切片也會受到影響。

          3)與數(shù)組的差異

          使用切片相比數(shù)組的優(yōu)勢在于其動態(tài)性和靈活性,能夠根據(jù)需要動態(tài)地調(diào)整長度,并且可以方便地進行切片的操作和擴展。

          1. 長度的靈活性:數(shù)組具有固定的長度,切片具有動態(tài)長度
          2. 內(nèi)存管理:數(shù)組在聲明時會分配一段連續(xù)的內(nèi)存空間,而切片則是一個引用類型,它包含了指向底層數(shù)組的指針、長度和容量。
          3. 傳遞和賦值行為:數(shù)組在傳遞給函數(shù)或賦值給新變量時會進行值拷貝,這意味著會復(fù)制整個數(shù)組的內(nèi)容。而切片在傳遞和賦值時是傳遞的引用,不會復(fù)制底層數(shù)組的內(nèi)容,多個切片可以共享同一個底層數(shù)組。
          4. 動態(tài)操作:由于切片具有動態(tài)長度,可以使用內(nèi)置函數(shù) appendcopy 來動態(tài)擴展切片的長度和復(fù)制切片的內(nèi)容。而數(shù)組的長度固定,無法直接進行動態(tài)操作,需要創(chuàng)建一個新的數(shù)組并進行元素的復(fù)制。

          在實際的開發(fā)中,切片比數(shù)組更常用,切片提供了靈活性和便利性,同時可以避免不必要的內(nèi)存復(fù)制。數(shù)組通常用于特定的場景,比如需要確切長度和固定內(nèi)存布局的情況。

          3、Map

          1)基本概念

          • Map 是一種無序的鍵值對的集合。它同時是一種集合,所以我們可以像迭代數(shù)組和切片那樣迭代它。不過,Map 是無序的,遍歷 Map 時返回的鍵值對的順序是不確定的。
          • 在獲取 Map 的值時,如果鍵不存在,返回該類型的零值,例如 int 類型的零值是 0,string 類型的零值是 ""。
          • Map 是引用類型,如果將一個 Map 傳遞給一個函數(shù)或賦值給另一個變量,它們都指向同一個底層數(shù)據(jù)結(jié)構(gòu),因此對 Map 的修改會影響到所有引用它的變量。

          2)創(chuàng)建方式

          1. 利用內(nèi)建函數(shù) make 創(chuàng)建
                
                // 創(chuàng)建一個空的 Map
          m := make(map[string]int)

          // 創(chuàng)建一個初始容量為 10 的 Map
          m := make(map[string]int10)
          1. 使用字面量創(chuàng)建
                
                // 使用字面量創(chuàng)建 Map
          m := map[string]int{
              "apple"1,
              "banana"2,
              "orange"3,
          }
          39342f6146a3a5a67f958dc8ef3c7220.webp

          4、結(jié)構(gòu)體

          1)基本概念

          在 Go 編程語言中,是沒有類似于其他面向?qū)ο缶幊陶Z言中的傳統(tǒng)對象的概念。

          Go 是一種結(jié)構(gòu)化編程語言,它鼓勵使用結(jié)構(gòu)體(struct)和方法(method)來組織和抽象代碼。

          結(jié)構(gòu)體可以包含字段(fields),這些字段可以是不同的數(shù)據(jù)類型,如整數(shù)、字符串、數(shù)組等。結(jié)構(gòu)體還可以擁有方法,方法是與結(jié)構(gòu)體關(guān)聯(lián)的函數(shù)。

          盡管 Go 中沒有傳統(tǒng)意義上的對象,但可以通過結(jié)構(gòu)體和方法來實現(xiàn)面向?qū)ο蟮木幊田L(fēng)格。你可以將結(jié)構(gòu)體看作是數(shù)據(jù)的容器,方法則可以看作是操作這些數(shù)據(jù)的函數(shù)。通過定義方法,可以在結(jié)構(gòu)體上執(zhí)行各種操作,從而實現(xiàn)面向?qū)ο蟮姆庋b、繼承和多態(tài)等概念。

          2)繼承

          Go 編程語言中,沒有傳統(tǒng)意義上的類繼承的概念,但是可以通過其他方式實現(xiàn)類似的功能。可以通過 結(jié)構(gòu)體嵌入 來實現(xiàn)一種類似于繼承的行為。

          3)聲明方式

          結(jié)構(gòu)(結(jié)構(gòu)的縮寫)用于將不同數(shù)據(jù)類型的成員集合創(chuàng)建到單個變量中。數(shù)組用于將相同數(shù)據(jù)類型的多個值存儲到單個變量中,而結(jié)構(gòu)用于將不同數(shù)據(jù)類型的多個值存儲到單個變量中。

          定義
                
                type structName struct {  
            member1 datatype;  
            member2 datatype;  
            member3 datatype;
            ...  
          }
          323b216a7ff9be3ed0090546f874dd96.webp
          使用
          1. 使用 var 關(guān)鍵字var v1 Vertex這里我們并不需要為結(jié)構(gòu)初始化
          2. 使用 := 標(biāo)識符v1 := Vertex{}

          嵌套結(jié)構(gòu) 寫法1:78b4f9afe347efc1b3a593d48ddd3a38.webp寫法2:0396c78a400e14e731337dc9f2e31f49.webp

          5、接口

          Go 語言中的接口是隱式實現(xiàn)的,也就是說,如果一個類型實現(xiàn)了一個接口定義的所有方法,那么它就自動地實現(xiàn)了該接口。因此,我們可以通過將接口作為參數(shù)來實現(xiàn)對不同類型的調(diào)用,從而實現(xiàn)多態(tài)。

                
                // 定義接口
          type interfaceName interface {
             method_name1 [return_type]
             method_name2 [return_type]
          }

          // 定義結(jié)構(gòu)體
          type structName struct {
             /* variables */
          }

          // 實現(xiàn)接口方法
          func (struct_name structName) methodName() [returnType] {
             /* 方法實現(xiàn) */
          }

          例子:390845a5a37f0245072b12bcd0d55b9e.webp

          6、指針

          在 Go 中,指針(pointer)是一種變量,它存儲了一個值的內(nèi)存地址。換句話說,指針指向內(nèi)存中存儲的數(shù)據(jù)的位置。

          當(dāng)用于操作變量時,&* 是 Go 語言中的兩個操作符,具有不同的含義。

          1. & 操作符(取地址操作符):
          • 當(dāng)用于變量之前,& 操作符用于獲取變量的內(nèi)存地址。
          • 例如:&x 表達(dá)式表示獲取變量 x 的內(nèi)存地址。
          * 操作符(解引用操作符):
          • 當(dāng)用于指針變量之前,* 操作符用于獲取指針指向位置的值。
          • 例如:*ptr 表達(dá)式表示獲取指針 ptr 指向位置的值。

          這兩個操作符在使用指針時經(jīng)常一起使用,配合使用可以實現(xiàn)指針的創(chuàng)建、操作和訪問。例子:

          919cfe83ee5f147cb2a786c374db4a0e.webp

          6 六)異常

          Go 中,通過顯式的、單獨的返回值來傳達(dá)錯誤是慣用的。Go語言鼓勵使用返回錯誤值的方式來處理異常情況,而不是通過拋出和捕獲異常來處理錯誤。

          Go 語言通過內(nèi)置的錯誤接口提供了非常簡單的錯誤處理機制。error 類型是一個接口類型,定義如下:

                
                type error interface {
              Error() string
          }

          我們可以在編碼中通過實現(xiàn) error 接口類型來生成錯誤信息。96b5e0f5309188a2287590d7ca3fca4e.webp

          7 七)并發(fā)

          在Go語言中,使用并發(fā)可以通過goroutine和通道(channel)來實現(xiàn)。Goroutine是一種輕量級的線程,可以與其他goroutine并發(fā)運行,而通道是用于goroutine之間進行通信和數(shù)據(jù)同步的機制。

          1)Goroutine

          f1b9f923590a56c51dc470c6498d146b.webpGo 允許使用 go 語句開啟一個新的運行期線程, 即 goroutine,以一個不同的、新創(chuàng)建的 goroutine 來執(zhí)行一個函數(shù)。同一個程序中的所有 goroutine 共享同一個地址空間。

          2)Channel

          通道(channel)是用來傳遞數(shù)據(jù)的一個數(shù)據(jù)結(jié)構(gòu)。可用于兩個 goroutine 之間通過傳遞一個指定類型的值來同步運行和通訊。操作符 <- 用于指定通道的方向,發(fā)送或接收。如果未指定方向,則為雙向通道。

                
                ch <- v    // 把 v 發(fā)送到通道 ch
          v := <-ch  // 從 ch 接收數(shù)據(jù); 并把值賦給 v

          注意:默認(rèn)情況下,通道是不帶緩沖區(qū)的。發(fā)送端發(fā)送數(shù)據(jù),同時必須有接收端相應(yīng)的接收數(shù)據(jù)。

          8b5d4d312a23c75b199aa6ecaed02a75.webp

          通道緩沖區(qū)

          通道可以設(shè)置緩沖區(qū),通過 make 的第二個參數(shù)指定緩沖區(qū)大小:

                
                ch := make(chan int100)
          • 帶緩沖區(qū)的通道允許發(fā)送端的數(shù)據(jù)發(fā)送和接收端的數(shù)據(jù)獲取處于異步狀態(tài),就是說發(fā)送端發(fā)送的數(shù)據(jù)可以放在緩沖區(qū)里面,可以等待接收端去獲取數(shù)據(jù),而不是立刻需要接收端去獲取數(shù)據(jù)。
          • 由于緩沖區(qū)的大小是有限的,所以還是必須有接收端來接收數(shù)據(jù)的,否則緩沖區(qū)一滿,數(shù)據(jù)發(fā)送端就無法再發(fā)送數(shù)據(jù)了。

          注意:如果通道不帶緩沖,發(fā)送方會阻塞直到接收方從通道中接收了值。如果通道帶緩沖,發(fā)送方則會阻塞直到發(fā)送的值被拷貝到緩沖區(qū)內(nèi);如果緩沖區(qū)已滿,則意味著需要等待直到某個接收方獲取到一個值。接收方在有值可以接收之前會一直阻塞。

          通道遍歷

          Go 通過 range 關(guān)鍵字來實現(xiàn)遍歷讀取到的數(shù)據(jù),類似于與數(shù)組或切片。格式如下:

                
                v, ok := <-ch
          1. 如果通道中有可接收的值,那么接收操作會成功,將該值賦給變量 v,同時 ok 的值為 true
          2. 如果通道已經(jīng)關(guān)閉且沒有可接收的值,那么接收操作會立即返回,并將變量 v 的零值賦給它,同時 ok 的值為 false12b86e7bd8da54db2a9b1660d96e8c77.webp

          defer 是 Go 語言中的一個關(guān)鍵字,用于延遲(defer)函數(shù)或方法的執(zhí)行。當(dāng)在函數(shù)或方法中使用 defer 關(guān)鍵字來延遲函數(shù)的執(zhí)行時,被延遲執(zhí)行的函數(shù)會在包含它的函數(shù)或方法即將返回之前被調(diào)用。


          通過本文的介紹,你應(yīng)該對Go語言的入門有了更好的了解。在繼續(xù)深入學(xué)習(xí)Go語言的過程中,你將會發(fā)現(xiàn)它的強大之處。你可以進一步學(xué)習(xí)高級的并發(fā)模型、標(biāo)準(zhǔn)庫中豐富的功能和第三方庫的使用,以及構(gòu)建實際應(yīng)用程序的最佳實踐。

          希望本文能夠為你提供一個良好的起點,激發(fā)你對Go語言的興趣,并為你進一步探索和學(xué)習(xí)提供指導(dǎo)。


          瀏覽 126
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  无吗中文 | 午夜激情在线观看 | 成人精品天堂一区二区三区五区 | 午夜精品视频在线 | www.国产三级 |