Go語言學習筆記(五)-其他類型(指針、結構體、、)

指針

在Go語言中也存在指針,且指針保存了變量的地址,初始值為nil。定義指針與定義變量相似,不同的是在類型前面指針需要加*例如:

var p *int   //此處定義了一個int類型的指針

指針也可以通過已有變量獲取,通過&操作符便可,與C語言相似Go中*指針名指向變量底層,但是不同的是Go中沒有指針運算。示例代碼如下:

package main
import "fmt"
func main(){
    i,j := 10,1000
    var p *int //定義一個int指針
    p = &i  //從i變量中獲取指向i的指針并賦值給p
    fmt.Println(i)
    *p = 21  //修改p指針指向的底層存儲的數據
    fmt.Println(i)
    p = &j
    *p = *p/10
    fmt.Println(j)
}

結構體

結構體就是一些字段的集合,通過type來聲明定義類型,并用struct來聲明結構體。具體實現如下:

package main
import "fmt"
type TestType struct{
    x int
    y int
}
func main(){
    p := TestType{1,2}
    fmt.Println(p)
    p.x = 4
    fmt.Println(p)
}

從上述示例代碼中可以看出結構體的字段通過點號來訪問。
結構體還可以通過指針來訪問,若一個結構體指針為p那么我們可以通過(&p).x來調用結構體的字段或者使用隱式間接引用,直接寫p.x就可以。結構體文法可以通過直接列出字段的值來新分配一個結構體,也可以通過Name:語法列出部分字段。

數組

類型[n]T表示擁有n個T類型的值得數組。數組的長度是數組的一部分,所以數組不能改變大小。
為了解決這個限制,Go推出了切片這一類型,切片為數組元素提了供動態大小,靈活的視角,比數組更實用。切片通過[]T來定義。切片不存儲任何數據,它只是描述了底層數組中的一段,或者我們也可以理解為切片其實相當于對數據中的一段的每一個元素都獲取了一個指針對象存放到另一數組中。創建數組與切片的方法如下:

package main
import "fmt"
func main(){
    //創建一個數組并設置初始值Go自動推導類型
    myArray := [10]int{1,2,3,4,5,6,7,8,9,10}
    fmt.Println(myArray)
    //創建一個數組設置初始值
    var myArray1 [5]int = [5]int{6,5,4,3,2}
    fmt.Println(myArray1)
    //創建一個切片初始元素個數為5,默認值為0,預留10個存儲空間
    mySlice := make([]int,5,10)
    fmt.Println(mySlice)
    //從數組上直接創建一個切片,初始元素個數與數組相同
    mySlice2 := []int{1,2,3,4,5}
    fmt.Println(mySlice2)
    //穿件一個切片元素個數為6默認值為0
    mySlice3 := make([]int,6)
    fmt.Println(mySlice3)
}

通過make方式來創建的切片也是創建動態數組的方法。
在進行切片時,可以利用它的默認行為來忽略上下界,切片的下界默認為0,上界為該切片的長度。例如:

package main
import "fmt"
func main(){
    var a [10]int = {1,2,3,4,5,6,7,8,9,10}
    fmt.Println(a[0:10])
    fmt.Println(a[:10])
    fmt.Println(a[:10])
    fmt.Println(a[:])
}

以上四個切片是等價的

切片擁有容量與長度兩個屬性,長度就是包含的元素個數,容量就是從第一個元素開始到底層數組元素的末尾的個數,長度與容量分別用len(s)和cap(s)來獲取。切片的零值為nil,nil切片的容量與長度為0,且沒有底層數組。
切片可以包含任何類型,包括切片。
切片可以通過append來追加元素,該函數為自建函數,使用方式如下:

package main
import "fmt"
func main(){
    var s []int
    printSlice(s)
    //輸出len=0 cap=0 []
    //追加一個元素
    s = append(s,0)
    printSlice(s)
    //輸出len=0 cap=0 []
    //追加多個元素
    s = append(s,2,3,4,5)
    printSlice(s)
    //輸出len=1 cap=1 [0]
}
func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

上述代碼展示了append的兩種使用方式,添加一個元素與添加多個元素

映射(map)

映射就是將鍵映射到值,映射的零值為nil,nil既沒有鍵也不能添加鍵,make函數會返回給定類型的映射,并將其初始化備用。映射的文法與結構體相似,但是映射必須要有鍵名。若頂級類型只有一種類型,那么可以在文法元素中忽略。

package main

import "fmt"

type Vertex struct {
    Lat, Long float64
}

var m = map[string]Vertex{
    "Bell Labs": {40.68433, -74.39967},
    "Google":    {37.42202, -122.08408},
}

func main() {
    fmt.Println(m)
    //輸出map[Bell Labs:{40.68433 -74.39967} Google:{37.42202 -122.08408}]

    //修改Bell Labs對應的元素
    m["Bell Labs"] = Vertex{2000,-74.39967}
    fmt.Println(m)
    //輸出map[Bell Labs:{2000 -74.39967} Google:{37.42202 -122.08408}]
    
    //刪除Bell Labs對應的元素
    delete(m,"Bell Labs")
    fmt.Println(m)
    //輸出map[Google:{37.42202 -122.08408}]

    //通過雙賦值來判斷鍵是否存在
    v, ok := m["Google"]
    fmt.Println("The value:", v, "Google?", ok)
    //輸出The value: {37.42202 -122.08408} Google? true
}

range

for循環的range形式可以遍歷切片也可以遍歷映射,for循環遍歷切片時,每次遍歷都會返回兩個值,一個是元素的下標一個是元素的副本,通過_可以將下標或者值忽略,當只需要下標時可以直接去掉,value部分。

package main

import (
    "golang.org/x/tour/wc"
    "strings"
)

func WordCount(s string) map[string]int {
    res := make(map[string]int)
    strs := strings.Fields(s)
    for _,v:= range strs{
        res[v]++
    }
    return res
}

func main() {
    wc.Test(WordCount)
}

函數值與閉包

Go中函數也是值,也可以作為參數或者返回值。Go函數可以是一個閉包。閉包是一個函數值,它引用了其函數體之外的變量。該函數可以訪問并賦予其引用的變量的值,換句話說,該函數被“綁定”在了這些變量上。

package main

import "fmt"

func main() {
    var j int = 5
    //此處創建了一個匿名函數,返回值為函數值,并通過匿名函數后跟()來執行這個匿名函數將返回的函數值賦值給a變量
    a := func()(func()){
        var i int = 10
        return func(){
            fmt.Printf("i,j: %d , %d\n",i,j)
        }
    }()
    a()
    j *= 2
    a()
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 出處---Go編程語言 歡迎來到 Go 編程語言指南。本指南涵蓋了該語言的大部分重要特性 Go 語言的交互式簡介,...
    Tuberose閱讀 18,501評論 1 46
  • 指針是C語言中廣泛使用的一種數據類型。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數據結構; ...
    朱森閱讀 3,473評論 3 44
  • 原文鏈接 http://ironxu.com/709 本文是學習 A Tour of Go (中文參考 Go 之旅...
    好剛編程閱讀 563評論 0 5
  • 滾動沖突解決 解決EditText換行后,ScrollView跟隨滾動的問題重寫ScrollView的comput...
    deathswing閱讀 406評論 1 0
  • 18.35分的天空。
    曹小閣閱讀 184評論 0 0