• 认真地记录技术中遇到的坑!
  • 能摸鱼真是太好啦!嘿嘿嘿!

Go语言内置数据结构:数组切片、结构、map

Go 悠悠 5年前 (2019-02-15) 4451次浏览 0个评论

Go语言数组和切片(Array,Slice)

数组是Go语言自带的数据结构,数组元素可以是任意的原始类型例如整形、字符串或者自定义类型。索引从0开始。

Go语言数组定义

数组声明语法:var variable_name [SIZE] variable_type

// 声明一个具有10个int类型元素的数组
var arr1 [10] int16

// 数组初始化
var arr2 = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

// 初始化时可以不指定数组大小
var arr3 = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

// 可以直接使用下标访问数组
arr3[1] = 20.0

// 声明一个不定长的数组
var arr4 []int

Go语言多维数组

Go 语言支持多维数组,以下为常用的多维数组声明方式:var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type

// 初始化二维数组
arr = [3][4]int{  
 {0, 1, 2, 3} ,   /*  第一行索引为 0 */
 {4, 5, 6, 7} ,   /*  第二行索引为 1 */
 {8, 9, 10, 11},   /* 第三行索引为 2 */
}

/* 输出数组元素 */
for  i = 0; i < 5; i++ {
  for j = 0; j < 2; j++ {
     fmt.Printf("a[%d][%d] = %d\n", i,j, a[i][j] )
  }
}

Go语言切片

Go 语言切片是对数组的抽象。Go 数组的长度不可改变,而切片长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

切片定义时不需要声明长度:var identifier []type

也可以使用make()函数来创建切片:var slice1 []type = make([]type, len),或者简写为:slice1 := make([]type, len),其中 len 是数组的长度并且也是切片的初始长度。

切片初始化类似于数组:s :=[] int {1,2,3 }

可以对切片进行截取:

  • s := arr[:]:初始化切片s,是数组arr的引用
  • s := arr[startIndex:endIndex]:将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片
  • s := arr[startIndex:]:缺省endIndex时将表示一直到arr的最后一个元素
  • s := arr[:endIndex]:缺省startIndex时将表示从arr的第一个元素开始

切片容量处理函数:

  • len(x): 切片长度
  • cap(x): 切片容量

一个切片在未初始化之前默认为 nil,长度为 0。

切片的维护(增删改)

定义切片后可以对切片中的元素增删改。

  • 定义并初始化切片: arr := []int{1, 2, 3}
  • 向切片添加元素: arr = append(arr, 5, 6)
  • 修改切片元素: arr[0] = 10
  • 删除切片最后一个元素: arr = arr[:len(arr) - 1]
  • 从切片arr拷贝元素到arr_new: copy(arr_new, arr)

Go语言数组作为参数传递方法

数组可以作为参数传递给函数,使用方法如下:

func main() {
    var array = []int{1, 2, 3, 4, 5}
    /* 未定义长度的数组只能传给不限制数组长度的函数 */
    setArray(array)
    /* 定义了长度的数组只能传给限制了相同数组长度的函数 */
    var array2 = [5]int{1, 2, 3, 4, 5}
    setArray2(array2)
}

func setArray(params []int) {
    fmt.Println("params array length of setArray is : ", len(params))
}

func setArray2(params [5]int) {
    fmt.Println("params array length of setArray2 is : ", len(params))
}

Go语言集合(Map)

Map 是一种无序的键值对的集合,是一种非常常用的数据结构。

定义Map

可以使用内建函数 make 也可以使用 map 关键字来定义 Map:

/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对

map的维护

先看下面的实例

package main

import "fmt"

func main() {
    var countryCapitalMap map[string]string /*创建集合 */
    countryCapitalMap = make(map[string]string) // 初始化map

    /* map插入key - value对,各个国家对应的首都 */
    countryCapitalMap [ "France" ] = "Paris"
    countryCapitalMap [ "Italy" ] = "罗马"
    countryCapitalMap [ "Japan" ] = "东京"
    countryCapitalMap [ "India " ] = "新德里"

    /*使用键输出地图值 */ 
    for country := range countryCapitalMap {
        fmt.Println(country, "首都是", countryCapitalMap [country])
    }

    /*查看元素在集合中是否存在 */
    captial, ok := countryCapitalMap [ "美国" ] /*如果确定是真实的,则存在,否则不存在 */
    if (ok) {
        fmt.Println("美国的首都是", captial)
    } else {
        fmt.Println("美国的首都不存在")
    }
}

map的维护(增删改)

  • 定义一个key和value都是string的map并初始化: var map1 = map[string]string{"test": "test", "uu": "uu"}
  • 往map中插入元素: map1["insert"] = "insert"
  • 修改map中key为test的元素: map1["test"] = "modify"
  • 删除map中key为test的元素: delete(map1, "test")

Go语言结构体

类似于C语言中的结构,Go语言中提供结构体struct来组合一系列具有相同类型或不同类型的数据。

结构体使用typestruct关键字来定义。

type struct_variable_type struct {
   member definition;
   member definition;
   ...
   member definition;
}

定义完结构体之后,才能使用该结构体来声明该结构体类型的变量。未初始化的结构成员值为0或者空。

// 使用结构体定义变量的两种方法
variable_name := structure_variable_type {value1, value2...valuen} // 按照结构体定义顺序依次绑定初始值

// 使用key=>value方式指定特定的成员值
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}

下面是一个简单实例:

package main

import "fmt"

type User struct {
   name string
   age int
   gender string
}

func main() {
    uu := User{"uusama", 22, "unknown"}
    tom := User{name: "tom", gender: "male"}
    fmt.Println(uu)  // {uusama 22 unknown}
    fmt.Println(tom) // {tom 0 male}
}

访问结构体成员

可以使用点.运算符对结构体的成员进行操作。

// 定义结构体
type User struct {
   name string
   age int
   gender string
}

// 声明一个User结构变量
var User uu
// 访问结构成员
uu.name = "uusama"
fmt.Println(uu) // {uusama 0 ""}

结构体作为函数参数

结构体类型可以像其他基本数据类型一样作为参数传递给函数,需要注意的是结构体作为参数传递时是值传递,在函数内修改结构体时,并不能作用于形参。

package main

import "fmt"

// 定义结构体User
type User struct {
    name string
    age int
    gender string
}

func addYear(user User, year int) User{
    user.age += year
    return user
}

func main() {
    uu := User{"uusama", 22, "unknown"}
    fmt.Println(uu)   // {uusama 22 unknown}

    var uuModify = addYear(uu, 10)
    // 修改后 uu 并没有发生改变
    fmt.Println(uu)  // {uusama 22 unknown}
    fmt.Println(uuModify)  // {uusama 32 unknown}
}

结构体指针

类似于其他指针变量你可以定义指向结构体的指针,如:var user_pointer *User

  • 可以通过&取得结构体的地址并赋值给结构指针
  • 可以直接通过.访问结构指针中的成员变量
  • 可以通过传递结构的指针作为函数参数,从而达到修改形参的目的

看下面的实例:

package main

import "fmt"

type User struct {
    name string
    age int
    gender string
}

// 定义包含结构指针的函数
func addYear(user *User, year int) User{
    user.age += year
    return *user
}

func main() {
    uu := User{"uusama", 22, "unknown"}
    fmt.Println(uu)   // {uusama 22 unknown}

    // 声明结构指针
    var uuPointer *User
    // 将uu结构的地址赋值给结构指针
    uuPointer = &uu

    // 通过 . 访问结构指针指向结构的成员
    uuPointer.age = 30
    fmt.Println(uu)  // {uusama 30 unknown}
    fmt.Println(uuPointer) // &{uusama 30 unknown}

    // 通过结构指针参数实现修改形参
    uuModify := addYear(&uu, 10)
    fmt.Println(uu)  // {uusama 40 unknown}
    fmt.Println(uuModify)  // {uusama 40 unknown}
}

遍历利器:range

Go语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。

在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值。

nums := []int{1, 2, 3, 4}
sum := 0
// 遍历切片nums,并求和
for _, num := range nums {
    sum += num
}
fmt.Println("sum: ", sum)  // sum:  10

m := map[string]int{"a": 10, "b": 15, "c": 20}
for key, value := range m {
    println("key:", key, "value:", value)
}

喜欢 (1)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址