go基础之基本数据结构(数组、slice、map)

go基本的数据结构有数组、slice、map,高级数据结构为结构体为用户自定义类型。本片文章主要讲解三大基本数据结构。

数组

数组是包含单个类型的元素序列,但是长度固定的数据类型,一个数组声明时需要指定数据类型和长度进行。例如定义长度为6的整形数组

var x [6]int

声明一个数组x用于存储int类型的元素且长度为6,所以数组x将由6个整数元素组成。

  • 声明一个数组并赋值
import (
    "fmt"
)
func main() {
    var x [5]int
    x[0] = 10
    x[1] = 20
    x[2] = 30
    x[3] = 40
    x[4] = 50
    fmt.Println(x)
}

//输出为:
[10 20 30 40 50]
  • 使用一行或者多行语句声明数组
x := [5]int{10, 20, 30, 40, 50}

x := [5]int{
    10,
    20,
    30,
    40,
    50,
}
  • 用…初始化数组
x := [...]int{10, 20, 30, 40, 50}
  • 初始化为特定值
package main

import "fmt"

func main() {
    x := [5]int{2: 10, 4: 40}
    fmt.Println(x)
}
//输出为:
[0 0 10 0 40]

其中10赋值给第三个元素,40赋值给第五个元素。

slice

slice是一种非常类似于数组的数据结构,但没有指定的长度。它是一种基于数组类型构建的抽象,提供了一种更方便处理集合的方法。与常规数组不同,slice是动态数组,其中slice的长度可以在数据增加或收缩的时候进行更改。当无法预测有多少个元素要存储到集合中的时候,slice是非常有用的数据结构。

slice中有两个概念:一是len长度,二是cap容量,长度是指已经被赋过值的最大下标+1,可通过内置函数len()获得。容量是指slice目前可容纳的最多元素个数,可通过内置函数cap()获得。slice是引用类型,因此在当传递slice时将引用同一指针,修改值将会影响其他的对象。

  • 定义一个空的Slice
var x []int
  • 用make函数定义一个Slice

用make函数声明slice时,可以显式指定slice的长度和容量。

x := make([]int, 5,10) //声明长度为5,容量为10的slice 
x := make([]int, 5) //声明长度为5的slice
  • 直接定义并且初始化一个slice

x:= []int{10, 20, 30, 40, 50} //长度为5,容量为5
x:= []int{} //长度为0,容量为0,当你想从函数返回空集合时,空片是有用的。
  • 初始化制定某个元素值
x := []int{4: 0} //第5个元素为0
  • append和copy
    切片可以通过内置函数append(slice []Type,elems…Type)追加元素,elems可以是一排type类型的数据,也可以是slice,如果将一个slice追加到另一个slice中需要带上”…”,这样才能表示是将slice中的元素依次追加到另一个slice中。
s :=append(s,1,2,3,4)
s :=append(s,s1...)

代码示例:

package main

import "fmt"

func main() {
    x := []int{10,20,30}
    y := append(x, 40, 50)
    fmt.Println(x, y)
}
//输出为:
[10 20 30] [10 20 30 40 50]
package main

import "fmt"

func main() {
    x := []int{10, 20, 30}
    y := make([]int, 2)
    copy(y, x)
    fmt.Println(x, y)
}
//输出为
[10 20 30] [10 20]
  • Length 和 Capacity
package main

import "fmt"

func main() {
    x := make([]int, 2, 5)
    x[0] = 10
    x[1] = 20
    fmt.Println(x)
    fmt.Println("Length is", len(x))
    fmt.Println("Capacity is", cap(x))
    x = append(x, 30, 40, 50)
    fmt.Println(x)
    fmt.Println("Length is", len(x))
    fmt.Println("Capacity is", cap(x))
    fmt.Println(x)
    x = append(x, 60)
    fmt.Println("Length is", len(x))
    fmt.Println("Capacity is", cap(x))
    fmt.Println(x)
}
//输出为:
[10 20]
Length is 2
Capacity is 5
[10 20 30 40 50]
Length is 5
Capacity is 5
[10 20 30 40 50]
Length is 6
Capacity is 12
[10 20 30 40 50 60]
  • 遍历slice
package main

import "fmt"

func main() {
    x := []int{10, 20, 30, 40, 50}
    for k, v := range x {
        fmt.Printf("Index: %d Value: %d\n", k, v)
    }
}
//输出为:
Index: 0 Value: 10
Index: 1 Value: 20
Index: 2 Value: 30
Index: 3 Value: 40
Index: 4 Value: 50

Map

哈希表是一种巧妙并且实用的数据结构。 它是一个无序的key/value对的集合, 其中所有的key都是不同的, 然后通过给定的key可以在常数时间复杂度内检索、 更新或删除对应的value。在Go语言中,一个map就是一个哈希表的引用,map类型可以写为map[K]V,其中K和V分别对应key和value。map中所有的key都有相同的类型, 所有的value也有着相同的类型,但是key和value之间可以是不同的数据类型。 其中K对应的key必须是支持==比较运算符的数据类型,所以map可以通过测试key是否相等来判断是否已经存在。

package main
import "fmt"
func main() {
    dict := make(map[string]string) //声明了一个key和value都是string类型的map
    dict["go"] = "Golang" //向map加入一个元素
    dict["cs"] = "CSharp"
    dict["rb"] = "Ruby"
    dict["py"] = "Python"
    dict["js"] = "JavaScript"
    for k, v := range dict {
        fmt.Printf("Key: %s Value: %s\n", k, v)
    }

    delete(dict, "go") // 删除dict["go"]
    fmt.Printf("after delete go in dict:\n")
    for k, v := range dict {
        fmt.Printf("Key: %s Value: %s\n", k, v)
    }

}
//输出为:
Key: cs Value: CSharp
Key: rb Value: Ruby
Key: py Value: Python
Key: js Value: JavaScript
Key: go Value: Golang

after delete go in dict:

Key: cs Value: CSharp
Key: rb Value: Ruby
Key: py Value: Python
Key: js Value: JavaScript

在获取值的时候有可能不在map当中,所以一般这样用:

goString, ok := dict["go"]
if !ok { /* "go" is not a key in this map; goString== "". */ }

//或者

if goString, ok := dict["go"]; !ok{
    /* "go" is not a key in this map; goString== "". */ 
}
posted @ 2018-07-01 15:36  0pandas0  阅读(321)  评论(0编辑  收藏  举报