乐趣区

关于goland:GO语言入门-五集合类型

进阶,进阶,向汇合类型登程。。。

汇合类型

很多同一个类型的元素放在一起的场景就是汇合。
数组(array),切片(slice),映射(map)都是 汇合类型,用以寄存同一类元素。

1. Array(数组)

数组寄存的是固定长度,雷同类型的数据
而且这些寄存的元素是间断的
寄存的数据类型没有限度

示例代码如下:

package main

import "fmt"

func main() {
    // 这里中括号外面的 5 示意的是数组的长度,前面花括号外面的是初始化
    array := [5]string{"a","b","c","d","e"}
    fmt.Println("array 的值为::", array)
}

运行后果为:

1.1 数组在内存中是间断寄存的,并且每个元素都有一个下标:


这里咱们就能够通过 array[下标] 来获取某个特定的元素:

package main

import "fmt"

func main() {
    // 这里中括号外面的 5 示意的是数组的长度,前面花括号外面的是初始化
    array := [5]string{"a","b","c","d","e"}
    fmt.Println("array 中第四个值为:", array[3])
}

运行后果为:

1.2 数组的长度能够省略

Go 语言会主动依据大括号两头元素的个数主动推导数组的长度。
这里只是实用于所有元素都被初始化的时候。

package main

import "fmt"

func main() {
    // 中括号外面用三个英文句号来省略数组的长度
    array := [...]string{"a","b","c","d","e"}
    fmt.Println("array 的值为:", array)
}

运行后果为:

如果只是初始化特定索引的元素做初始化,就不能省略数组长度了
没有初始化的元素其默认值都是数组类型的零值,string 就是空字符串

package main

import "fmt"

func main() {
    // 省略数组长度,只是初始化特定索引的话,数组长度就是最大的索引的长度
    array := [...]string{1:"a",3:"c"}
    fmt.Println("array 的长度为:", len(array))
}

运行后果为:

1.3 数组循环

大部分状况下应用的是 for range 这种 Go 语言的新型循环

package main

import "fmt"

func main() {array := [...]string{"a","b","c","d","e"}
    for i,v := range array{fmt.Println("key 为:", i, ", value 为:",v)
    }
    // 如果返回的值不须要,就能够用 _ 抛弃
    for _,v := range array{fmt.Println("value 为:", v)
    }
}

运行后果为:

2. Slice(切片)

切片和数组相似,能够把它了解为动静数组(切片的底层就是一个数组)
对数组任意分隔,就能够失去一个切片

package main

import "fmt"

func main() {array := [...]string{"a","b","c","d","e"}
    // 这里是从索引 2 开始到索引 5 完结,蕴含索引 2 但不蕴含索引 5
    slice := array[2:5]
    for i,v := range slice{fmt.Println("key 为:", i, ", value 为:",v)
    }
}

运行后果为:

2.1 基于数组生成切片

生成的切片也是能够依据索引获取元素的值
在数组 array 中,元素 c 的索引其实是 2
然而对数组切片后
在新生成的切片 slice 中,它的索引是 0
通过切片后,切片的索引范畴扭转了

2.2 切片是一个具备三个字段的数据结构:
  • 指向数组的指针 data
  • 长度 len
  • 容器 cap
2.3 切片申明
package main

import "fmt"

func main() {
    // 用 make 函数生成一个长度为 4,容量为 8 的切片
    // 切片的容量不能比切片的长度小
    slice1 := make([]string,4,8)
    fmt.Println(slice1)
}

运行后果为:

当通过 append 函数往切片中追加元素的时候,会追加到闲暇的内存上,当切片的长度要超过容量的时候,会进行扩容。

切片还能够通过字面量来初始化
通过字面量初始化的切片长度和容量雷同

package main

import "fmt"

func main() {
    // 切片申明和数组惟一的不同就是中括号外面不须要指定长度或者...
    slice1 := []string{"a","b","c","d","e"}
    fmt.Println("长度为:", len(slice1), ",容量为:", cap(slice1))
}

运行后果为:

2.3 Append 追加元素
// 追加一个元素
slice2 := append(slice1, "f")
// 追加多个元素
slice2 := append(slice1, "f", "g")
// 追加另一个切片
slice2 := append(slice1, slice3)

3. Map(映射)

map 是一个无需的 K-V 键值对汇合
构造为 map[K]V
其中 K 对应 KEY,V 对应 Value

3.1 Map 申明初始化

通过 make 形式创立

package main

import "fmt"

func main() {
    // 申明一个 map key 为 string 类型,value 为 int 类型
    nameAgeMap := make(map[string]int)
    // 如果 key 曾经存在就更新 key 对应的 value 值
    nameAgeMap["zhouzhaodong"] = 20
    fmt.Println(nameAgeMap)
}

运行后果为:

通过字面量形式创立

package main

import "fmt"

func main() {
    // 申明一个 map key 为 string 类型,value 为 int 类型
    nameAgeMap := map[string]int{"zhouzhaodong": 20}
    // 增加新的键值对
    nameAgeMap["xiaohua"] = 21
    fmt.Println(nameAgeMap)
}

运行后果为:

3.2 Map 获取和删除
// 增加新的键值对
nameAgeMap["xiaohua"] = 21
// 获取指定 Key 对应的 Value
age := nameAgeMap["xiaohua"]

map 的 [] 操作符能够返回两个值:

  1. 第一个值就是对应的 Value
  2. 第二个值标记该 Key 是否存在,如果存在,它的值为 true
package main

import ("fmt")

func main() {
    // 申明一个 map key 为 string 类型,value 为 int 类型
    nameAgeMap := map[string]int{"zhouzhaodong": 20}
    // 获取特定 key 的 value 值
    age, ok := nameAgeMap["zhouzhaodong1"]
    if ok {fmt.Println(age)
    } else {fmt.Println("该 key 不存在")
    }
}

运行后果为:

删除键值对间接应用 delete 函数即可

// 这里的 delete 函数有两个参数,第一个是 Map 汇合,第二个是 Key 值
delete(nameAgeMap, "zhouzhaodong")
3.3 遍历 Map

这里映射的遍历是无序的,每次遍历的程序可能不同

对于 map,for range 返回两个值:

  1. 第一个是 map 的 Key
  2. 第二个是 map 的 Value
package main

import ("fmt")

func main() {
    // 申明一个 map key 为 string 类型,value 为 int 类型
    nameAgeMap := map[string]int{"zhouzhaodong": 20}
    // 新增一个键值对
    nameAgeMap["小花"] = 21
    for k, v := range nameAgeMap{fmt.Println("key=", k, ",value=", v)
    }
}

运行后果为:

4. String 和 []byte

所有的字符串都是一个不可变的字节数列,所以能够间接转化为字节数组
字符串还能够间接应用 [] 获取对应索引的字节值

package main

import ("fmt")

func main() {
    s := "猜猜我的长度"
    bs := []byte(s)
    fmt.Println("s=", s)
    fmt.Println("bs=", bs)
    // UTF8 编码下,一个汉字是 3 个字节,所以这里 s 的长度为 18
    fmt.Println("s 的长度为:", len(s))
    fmt.Println(s[1], s[4], s[17])
}

运行后果为:

如果你想把一个汉字当做一个长度来计算的话,能够用如下办法

s := "猜猜我的长度"
// 这里打印的后果是 6
fmt.Println(utf8.RuneCountInString(s))
4.1 循环

应用 fro range 进行字符串的循环时,会主动的隐式解码 Unicode 字符串

package main

import ("fmt")

func main() {
    s := "猜猜我的长度"
    for i, v := range s{fmt.Println(i, v)
        // string(v) 将 Unicode 转为对应的汉字
        fmt.Println(i, string(v))
    }
}

运行后果为:

集体博客地址

http://www.zhouzhaodong.xyz/

退出移动版