go 復合類型: 數組、slice、map、結構體


一、數組

數組是具有固定長度且擁有零個或多個相同數據類型元素的序列。

聲明數組:

var a [3]int   // 默認情況下一個數組中的元素初始值為元素類型的零值, 對於Int是0
fmt.Println(a[0])  // 輸出0

初始化數組:

var q [3]int = [3]Int{1,2,3}  // 數組字面量初始化
var r [3]int   // 先聲明 ,后初始化  
r[0] = 1    
r[1] = 2
x := [...]int{1,2,3}    // 長度為初始化元素個數

y := [...]int{99: -1}   // 定義一個擁有100個元素的數組,並且出最后一個元素為-1外,其它元素都為0

使用數組:

fmt.Println(a[0])   // 輸出第一個元素
// 輸出索引和元素
for i,v := range a {
    fmt.Printf("%d %d\n", i,v)
}
// 僅輸出元素
for _,v := range a {
    fmt.Printf("%d\n", v)
}

// 獲取數組長度
fmt.Printf("%d\n", len(a))

二、切片(slice)

slice是表示一個擁有相同類型元素的可變長度的序列,通常寫成[]T。可以用來訪問數組的部分或全部元素,這個數組稱為slice的底層數組,slice有三個屬性:指針、長度、容量。指針指向數組的第一個可以從slice中訪問的元素,長度是指slice中元素的個數,它不能超過slice的容量。容量是指slice的起始元素到底層數組的最后一個元素之間的個數。slice的零值是nil。

創建slice:

// 創建一個底層數組
week := [...]string{"Monday", "Tuesday","Wednesday","Thursday","Friday","Saturday ","Sunday"}
// 從底層數組創建slice
weekend := week[5:7]  // [i:j]  取索引i-j-1的元素作為底層數組,[:j] 取第一個元素到j-1的元素, [1:]取第一個元素到最后一個元素, [:] 取所有元素

week := []int{1,2,3}
week := make([]int, 3,3)  // 創建長度為3,  容量為3的slice


使用slice

// 追加元素
week.append(1)  // 向slice week追加一個元素1
// 復制slice
var days = []int
copy(days, week)  // 將week復制給days

三、散列表(map)

散列表:map[key]value。key為鍵的類型,value為值的類型。map的零值是nil。

創建map:

// 使用make
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34
// 使用字面量
ages := map[string]int{"alice": 31, "charlie": 34}

遍歷map:

for name, age := ages {
    fmt.Printf("%s/t%d/n", name, age)
}

四、結構體

結構體是將零個或者任意類型的命名變量組合在一起的聚合數據類型,每個變量叫做結構體的成員。結構體成員的順序不同則結構體也不同(兩個結構體),如果結構體的成員首字母是大寫的,則這個成員變量是可導出的,否則不可導出。結構體中不可定義一個結構體自身類型的變量,但可定義一個自身類型的指針。結構體的零值有結構體成員的零值組成。

定義結構體:

type Employee struct {
    ID int
    Name string
    Address string
    Dob string
    Position string
    Salary string
    ManagerId string
}
// 定義一個空結構體
struct {}
// 空結構體可以用作map的值
week := make(map[string]struct{})

定義結構體變量:

var dilbert Employee

給結構體變量常用賦值和訪問結構體變量成員:

// 賦值
dilbert.Name = "alice"
// 取值
fmt.Printf("%s\n", dilbert.Name)

// 使用指針訪問
position := &dilbert.Position
fmt.Printf("%s\n", *position)

var employee *Employee = &dilbert
// 下面兩條語句是等價的
employee.Position = "proactive team player"
(*employee).Position = "proactive team player"

// 使用結構體字面量初始化
type Point struct {X,Y int}
e := Employee{ID: 1, Name: "alice"}  // 未賦值的成員將初始化為零值。
p = Point{1,2}
// 初始化結構體,並獲取指針
pp := &Point{1,2}
// 等價於
pp := new(Point)
*pp = Point{1,2}

結構體嵌套

type Point struct {X, Y int}
type Circle struct {
    Center Point
    Radius int
}
type Wheel struct {
    Circle Circle
    Spokes int
}
// 訪問嵌套成員
vat w Wheel
w.Circle.Center.X = 8
w.Circle.Center.Y = 8
w.Circle.Radius = 5
w.Spokes = 20
// 初始化(下面兩種方式是等價的)
w = Wheel{Circle{Point{8,8},5}, 20}
w = Wheel{
    Circle : Circle {
        Point: Point{X:8, Y: 8},
        Radius: 5,
    }
    Spokes: 20,
}

匿名成員

type Circle struct {
    Point    // 匿名成員,擁有一個隱式的名字Point(類型名),不能定義兩個相同類型的匿名成員
    Radius int
}
type Wheel struct {
    Circle
    Spokes int
}
// 訪問嵌套成員
vat w Wheel
w.X = 8
w.Y = 8
w.Radius = 5
w.Spokes = 20

結構體方法:

方法的聲明和函數類似,只是在函數名字前面多了一個參數,這個參數八這個方法綁定到這個參數對於的類型上。Go可以將方法綁定到任何類型上(指針類型和接口類型除外)。

// 結構體Point的方法, p 參數稱為方法的接收者(類似java中的this)
func (p Point) Distance(q Point) float64 {
    return math.Hypot(q.X-p.x, q.Y-p.Y)
}
// 方法調用
p := Point{1,2}
q := Point{4,6}
p.Distance(q)

// 使用類型Point的指針作為方法接收者
func (p *Point) ScaleBy(factor float64) {
    p.X *= factor
    p.Y *= factor
}
// 方法調用
p := &Point{1,2}
p.ScaleBy(2)
// 上面的調用可以簡寫成
p := Point{1,2}
p.ScaleBy(2)  // 編譯器會為p執行 &p

五、JSON

Go通過標准庫encoding/json對JSON提供了支持。

GO對象轉換JSON:

var employee []Employee
data: err := json.Marshal(employee)
data: err := json.MarshalIndent(employee, "", "  ")

六、接口

接口類型是對其它類型行為的概括與抽象。對於一個具體的類型,無需聲明它實現了哪些接口,只要提供接口所必需的方法即可。。

定義接口:

type Reader interface {
    Read(p []byte) (n int, err error)
}

嵌入式接口:

type Reader interface {
    Read(p []byte) (n int, err error)
}
type ReadWriter interface {
    Reader
    Writer
}

實現接口:

如果一個類型要實現接口,就必須實現接口類型中定義的所有方法

// 結構體File實現了接口Reader
type File struct {/**....**/}
func (f *File) Read(p []byte) {
    /**
    	.....
    **/
}

空接口:

interface {}
var any interface{}  // 可以把任何值賦給空接口類型。

接口值:

接口值分為一個接口的具體類型和該類型的一個值(動態類型和動態值)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM