Go 入門 - Go中的複雜類型

來源:互聯網
上載者:User

標籤:切片   ack   class   tps   刪除   VID   預設值   變數   cap   

主要內容來自中文版的官方教程Go語言之旅
目的為總結要點

指標

Go 擁有指標。指標儲存了值的記憶體位址。

類型 *T 是指向 T 類型值的指標。其零值為 nil

var p *int

& 操作符會產生一個指向其運算元的指標。

i := 42p = &i

* 操作符表示指標指向的底層值。

fmt.Println(*p) // 通過指標 p 讀取 i*p = 21         // 通過指標 p 設定 i

這也就是通常所說的“間接引用”或“重新導向”。

與 C 不同,Go 沒有指標運算。

package mainimport "fmt"func main() {    i, j := 42, 2701    p := &i         // point to i    fmt.Println(*p) // read i through the pointer    fmt.Println(p)    *p = 21         // set i through the pointer    fmt.Println(i)  // see the new value of i    p = &j         // point to j    *p = *p / 37   // divide j through the pointer    fmt.Println(j) // see the new value of j}// output// 42// 0xc420084010// 21// 73
結構體

結構體是一些變數的集合,可以用以下方式建立一個結構體。修改結構體可以採用.符號,指向結構體的指標也可以用同樣的方法來訪問。

package mainimport "fmt"type Vertex struct {    X int    Y int}func main() {    v := Vertex{1,2}    fmt.Println(v)    v.X = 4    fmt.Println(v)    p := &v    p.X = 8    fmt.Println(v)}//output {1 2} {4 2} {8 2}

結構體與結構體的指標都可以用以下的方法初始化

package mainimport "fmt"type Vertex struct {    X, Y int}var (    v1 = Vertex{1, 2}  // has type Vertex    v2 = Vertex{X: 1}  // Y:0 is implicit    v3 = Vertex{}      // X:0 and Y:0    p  = &Vertex{1, 2} // has type *Vertex)func main() {    fmt.Println(v1, p, v2, v3)}
數組與切片

數組的聲明也是從做到右的,以var開頭的或者短聲明

var a [2] stringvar a [10] intprimes := [6]{2, 3, 5, 7}
切片

類型[]T表示一個元素類型為T的切片。切片通過兩個下標界定a[low:high],這種切片會選擇一個半開區間,包含第一個元素但是排除最後一個元素。切片下界的預設值是0,上界的預設值是該切片的長度。這裡注意,如果制定了長度,那麼得到的就是數組,在Go中數組是作為值傳遞的,會耗費很多的記憶體。

package mainimport "fmt"func main() {    primes := [6]int{2, 3, 5, 7, 11, 13} // 這是一個數組    var s []int = primes[1:4] // 這是在聲明一個切片    fmt.Println(s)    names := [4]string{        "John","Paul","George","Ringo",    }   // 這是一個數組    fmt.Println(names)    a := names[0:2] // 這也是一個切片    b := names[1:3] // 這也是一個切片    fmt.Println(a, b) // output [John Pul] [Paul George]    b[0] = "XXX"    fmt.Println(a, b) // output [John XXX] [XXX George]    fmt.Println(names) // output [John XXX George Ringo]}

一個切片本身是底層數組的引用,多個切片可以共用一個底層數組,在一個切片上的修改可以影響到底層數組,進而影響到所有切片

切片擁有 長度容量。對於切片s,長度是切片的長度,可以用len(s)獲得,容量是從切片的第一個元素開始數一直到底層數組的長度,可以用cap(s)獲得。
從底層數組的視角來看,切片中有意義的量只有三個,分別是起始位置,長度和容量。其中長度和容量是反映在切片自身重點,起始位置是用於錨定切片在底層數組中的位置。一旦切片建立,那麼底層數組在起始位置之前的部分就會被扔掉。

在做切片的時候,其實s[low: high]中的low就選擇了在當前的底層數組中的起始位置,high選擇了終止位置,進而定義了長度high-low。在簡曆切片之後,底層數組精簡原底層數組中low到末尾的部分。

nil切片是切片長度和容量都為零,且沒有底層數組的切片,例如它可以這樣聲明var s []int。其實在這個意義上,數組自身就是長度和容量相等的切片。

切片可以包含任何類型,甚至其他的切片(多維陣列)

board := [][]string{        []string{"_", "_", "_"},        []string{"_", "_", "_"},        []string{"_", "_", "_"},}
range遍曆切片
package mainimport "fmt"var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}func main() {    for i, v := range pow {        fmt.Printf("2**%d = %d\n", i, v)    }    for _, value := range pow {        fmt.Printf("%d\n", value)    }    for value, _ := range pow {        fmt.Printf("%d\n", value)    }}
映射

映射將key映射到value。用make函數可以建立給定類型的映射,並將其初始化備用。

映射的零值為nil,需要注意的是nil既沒有鍵,也不能添加鍵

package mainimport "fmt"type Vertex struct {    Lat, Long float64}var m map[string]Vertexfunc main() {    m = make(map[string]Vertex)    m["Bell Labs"] = Vertex{        40.68433, -74.39967,    }    fmt.Println(m["Bell Labs"])}

映射的文法和結構體類似,但是一定要有鍵名

package mainimport "fmt"type Vertex struct {    Lat, Long float64}var m = map[string]Vertex{    "Bell Labs": Vertex{        40.68433, -74.39967,    },    "Google": Vertex{        37.42202, -122.08408,    },}func main() {    fmt.Println(m)}

映射可以用下標訪問或修改元素

delete函數刪除元素

用雙賦值可以檢測某個鍵的是否存在

package mainimport "fmt"func main() {    m := make(map[string]int)    m["Answer"] = 42    fmt.Println("The value:", m["Answer"])    m["Answer"] = 48    fmt.Println("The value:", m["Answer"])    delete(m, "Answer")    fmt.Println("The value:", m["Answer"])    v, ok := m["Answer"]    fmt.Println("The value:", v, "Present?", ok) // ok 是是否存在的boolean值}
函數值

函數本身也可以作為值,稱為函數值,可以作為函數的參數或者傳回值

package mainimport (    "fmt"    "math")func compute(fn func(float64, float64) float64) float64 {    return fn(3, 4)}func main() {    hypot := func(x, y float64) float64 {        return math.Sqrt(x*x + y*y)    }    fmt.Println(hypot(5, 12))    fmt.Println(compute(hypot))    fmt.Println(compute(math.Pow))}

Go函數可以使一個閉包。閉包是一個函數值,它引用了函數體之內的變數。該函數可以訪問並賦予其引用的變數的值。例如下面的例子中adder函數傳回值為一個閉包。每個閉包都被綁定在各自的sum變數上。

package mainimport "fmt"func adder() func(int) int {    sum := 0 //這是閉包的函數體之外的變數,它也被綁定在閉包內了    return func(x int) int { //這是閉包        sum += x        return sum    }}func main() {    pos, neg := adder(), adder()    for i := 0; i < 10; i++ {        fmt.Println(            pos(i),            neg(-2*i),        )    }}
make函數

用make函數建立切片(動態數組),有兩種用法

a := make([]int, 5) // 長度為5,容量預設為5b := make([]int, 0, 5) // 長度為0, 容量為5

func make([]T, len, cap) []T

make函數可以建立給定類型的映射,並將其初始化備用

Go 入門 - Go中的複雜類型

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.