golang第七卷---go中的数据结构

这篇具有很好参考价值的文章主要介绍了golang第七卷---go中的数据结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

分享一个go语言高级编程学习网站:Go语言高级编程

数组

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

因为数组的长度是固定的,所以在Go语言中很少直接使用数组。

Go语言数组的声明:

var 数组变量名 [元素数量]Type

数组是定长的,不可更改,在编译阶段就决定了

数组的定义方式:

var a [3]int                    // 定义长度为 3 的 int 型数组, 元素全部为 0
var b = [...]int{1, 2, 3}       // 定义长度为 3 的 int 型数组, 元素为 1, 2, 3
var c = [...]int{2: 3, 1: 2}    // 定义长度为 3 的 int 型数组, 元素为 0, 2, 3
var d = [...]int{1, 2, 4: 5, 6} // 定义长度为 6 的 int 型数组, 元素为 1, 2, 0, 0, 5, 6

Go 语言中数组是值语义。一个数组变量即表示整个数组,它并不是隐式的指向第一个元素的指针(比如 C 语言的数组),而是一个完整的值。当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。如果数组较大的话,数组的赋值也会有较大的开销。为了避免复制数组带来的开销,可以传递一个指向数组的指针,但是数组指针并不是数组。

关于函数间传递数组

var arr [10]int

func foo1(arr [10]int) { //每次拷贝整个数组
    ...
}

func foo2(arr *[10]int) { //传递指针,效率更高
    ...
}

字符串

一个字符串是一个不可改变的字节序列,字符串可以包含任意的数据,但是通常是用来包含可读的文本,字符串是 UTF-8 字符的一个序列。

字符串的定义:

var str string = "golang"

go语言从底层就支持UTF-8编码。

Go 语言字符串的底层结构在 reflect.StringHeader 中定义:

type StringHeader struct {
    Data uintptr
    Len  int
}

字符串结构由两个信息组成:第一个是字符串指向的底层字节数组,第二个是字符串的字节的长度。字符串其实是一个结构体,因此字符串的赋值操作也就是 reflect.StringHeader 结构体的复制过程,并不会涉及底层字节数组的复制。在前面数组一节提到的 [2]string 字符串数组对应的底层结构和 [2]reflect.StringHeader 对应的底层结构是一样的,可以将字符串数组看作一个结构体数组。

字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容。
当字符为 ASCII 码表上的字符时则占用 1 个字节

如果使用``反引号,会被原样进行赋值和输出

fmt.Println(`\t golang`)  // \t golang

字符串是字节的定长数组,byte 和 rune 都是字符类型,若多个字符放在一起,就组成了字符串

遍历

对于字符串中unicode字符集使用for range进行遍历,ascii字符集可以使用for range或者for循环遍历

	var str1 string = "hello"
	var str2 string = "hello,golang"
	// 遍历
	for i :=0; i< len(str1); i++{
		fmt.Printf("ascii: %c %d\n", str1[i], str1[i])
	}
	for _, s := range  str1{
		fmt.Printf("unicode: %c %d\n ", s, s)
	}
	// 中文只能用 for range
	for _, s := range  str2{
		fmt.Printf("unicode: %c %d\n ", s, s)
	}

字符串方法:

  1. ASCII字符使用len()函数获取字符串所占的字节长度
  2. Unicode字符串长度使用utf8.RuneCountInString()函数
	str3 := "hello"
    str4 := "你好"
    fmt.Println(len(str3))  // 1个字母占1个字节 4
    fmt.Println(len(str4))  // 1个中文占3个字节,go从底层支持utf8 6
    fmt.Println(utf8.RuneCountInString(str4)) // 2
  1. 字符串拼接符“+”,除了使用+进行拼接,也可以使用WriteString()
	str1 := "你好,"
	str2 := "golang"
	var stringBuilder bytes.Buffer
	//节省内存分配,提高处理效率
	stringBuilder.WriteString(str1)
	stringBuilder.WriteString(str2)
	fmt.Println(stringBuilder.String())
  1. 字符串的格式化:print:结果写到标准输出 Sprint:结果会以字符串形式返回
%c  单一字符
%T  动态类型
%v  本来值的输出
%+v 字段名+值打印
%d  十进制打印数字
%p  指针,十六进制
%f  浮点数
%b 二进制
%s string
  1. 字符串查找

strings.Index(): 正向搜索子字符串
strings.LastIndex():反向搜索子字符串

类型转换

在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值。由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明:

//类型 B 的值 = 类型 B(类型 A 的值)
valueOfTypeB = type B(valueOfTypeA)
  1. []byte和string可以通过强制类型转换
package main

import "fmt"

func main() {

	s1 := "localhost:8080"
	fmt.Println(s1)
	// 强制类型转换 string to byte
	strByte := []byte(s1)

	// 下标修改
	strByte[len(s1)-1] = '1'
	fmt.Println(strByte)

	// 强制类型转换 []byte to string
	s2 := string(strByte)
	fmt.Println(s2)
}
  1. 整数 与 字符串
// 字符串与其他类型的转换
// str 转 int
newStr1 := "1"
intValue, _ := strconv.Atoi(newStr1)
fmt.Printf("%T,%d\n", intValue, intValue)  // int,1

// int 转 str
intValue2 := 1
strValue := strconv.Itoa(intValue2)
fmt.Printf("%T, %s\n", strValue, strValue)
  1. 浮点数 与字符串

    // str 转  float
    string3 := "3.1415926"
    f,_ := strconv.ParseFloat(string3, 32)
    fmt.Printf("%T, %f\n", f, f)  // float64, 3.141593
    //float 转 string
	floatValue := 3.1415926
	//4个参数,1:要转换的浮点数 2. 格式标记(b、e、E、f、g、G)
	//3. 精度 4. 指定浮点类型(32:float32、64:float64)
	// 格式标记:
	// ‘b’ (-ddddp±ddd,二进制指数)
	// ‘e’ (-d.dddde±dd,十进制指数)
	// ‘E’ (-d.ddddE±dd,十进制指数)
	// ‘f’ (-ddd.dddd,没有指数)
	// ‘g’ (‘e’:大指数,‘f’:其它情况)
	// ‘G’ (‘E’:大指数,‘f’:其它情况)
	//
	// 如果格式标记为 ‘e’,‘E’和’f’,则 prec 表示小数点后的数字位数
	// 如果格式标记为 ‘g’,‘G’,则 prec 表示总的数字位数(整数部分+小数部分)
	formatFloat := strconv.FormatFloat(floatValue, 'f', 2, 64)
	fmt.Printf("%T,%s",formatFloat,formatFloat)

切片(slice)

切片就是一种简化版的动态数组(长度不固定)

切片的结构定义,reflect.SliceHeader:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

可以看出切片的开头部分和 Go 字符串是一样的,但是切片多了一个 Cap 成员表示切片指向的内存空间的最大容量(对应元素的个数,而不是字节数)

切片的定义方式:

var (
    a []int               // nil 切片, 和 nil 相等, 一般用来表示一个不存在的切片
    b = []int{}           // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
    c = []int{1, 2, 3}    // 有 3 个元素的切片, len 和 cap 都为 3
    d = c[:2]             // 有 2 个元素的切片, len 为 2, cap 为 3
    e = c[0:2:cap(c)]     // 有 2 个元素的切片, len 为 2, cap 为 3
    f = c[:0]             // 有 0 个元素的切片, len 为 0, cap 为 3
    g = make([]int, 3)    // 有 3 个元素的切片, len 和 cap 都为 3
    h = make([]int, 2, 3) // 有 2 个元素的切片, len 为 2, cap 为 3
    i = make([]int, 0, 3) // 有 0 个元素的切片, len 为 0, cap 为 3
)

添加切片元素

内置的泛型函数 append 可以在切片的尾部追加 N 个元素:

var a []int
a = append(a, 1)               // 追加 1 个元素
a = append(a, 1, 2, 3)         // 追加多个元素, 手写解包方式
a = append(a, []int{1,2,3}...) // 追加 1 个切片, 切片需要解包
//还可以在切片的开头添加元素
var b = []int{1,2,3}
b = append([]int{0}, b...)        // 在开头添加 1 个元素
b = append([]int{-3,-2,-1}, b...) // 在开头添加 1 个切片

删除切片元素

a = []int{1, 2, 3}
a = a[:len(a)-1]   // 删除尾部 1 个元素
a = a[:len(a)-N]   // 删除尾部 N 个元素
//删除开头的元素可以直接移动数据指针:
b = []int{1, 2, 3}
b = b[1:] // 删除开头 1 个元素
b = b[N:] // 删除开头 N 个元素

映射(map)

map 是一种无序的键值对的集合

map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,map 是无序的,我们无法决定它的返回顺序,这是因为 map 是使用 hash 表来实现的

创建和初始化

dict := make(map[string]int) 

dict := map[string]string{"Red":"#da1337", "Orange":"#e95a22"} 

切记不要使用new创建map,否则会得到一个空引用的指针

使用映射

colors := make(map[string]string)  //创建一个空映射

colors["Red"] = "#da1337" //赋值

var colors map[string]string
colors["Red"] = "#da1337" //error

value, ok := colors["Blue"] //判断键是否存在
if ok {
    fmt.Println(value)
}

value := colors["Blue"] //判断读取到的值是否空值
if value != "" {
    fmt.Println(value)
}

遍历
map 的遍历过程使用 for range 循环完成
如下:

scene := make(map[string]int)
scene["cat"] = 66
scene["dog"] = 4
scene["pig"] = 960
for k, v := range scene {
    fmt.Println(k, v)
}

map是无序的,不要期望 map 在遍历时返回某种期望顺序的结果

删除
使用 delete() 内建函数从 map 中删除一组键值对,delete() 函数的格式如下:

delete(map,)

Go语言中并没有为 map 提供任何清空所有元素的函数、方法,清空 map 的唯一办法就是重新 make 一个新的 map,不用担心垃圾回收的效率,Go语言中的并行垃圾回收效率比写一个清空函数要高效的多。

注意map 在并发情况下,只读是线程安全的,同时读写是线程不安全的。

来自各个文章的总结,其他go中的数据结构还在更新中,感谢阅读!文章来源地址https://www.toymoban.com/news/detail-772541.html

到了这里,关于golang第七卷---go中的数据结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构与算法】第七章-图【期末复习】

    图:有向图、网,无向图、网。 顶点 边:有向图图称作弧,分弧头弧尾。 依附:边依附点,边和点关联 邻接:点邻接点 度:点关联的边的数目 完全图: 无向: C n 2 C_n^2 C n 2 ​ 条边; 有向: 2 C n 2 2C_n^2 2 C n 2 ​ 条边 连通:若干结点互相可以通信,用手提起一个结点可以顺

    2024年02月01日
    浏览(58)
  • [数据结构 -- 手撕排序算法第七篇] 递归实现归并排序

    目录 1、归并的思想 2、归并排序的思想 2.1 基本思想 2.2 图解分析 3、归并排序递归版本代码实现 3.1 代码解析 3.2 注意事项 3.2.1错误划分:[begin, mid-1],[mid, end] 3.2.2 正确划分:[begin, mid], [mid+1, end] 4、归并排序的测试 5、时间复杂度、空间复杂度分析 5.1 时间复杂度 5.2 空间复杂

    2024年02月16日
    浏览(45)
  • 数据结构与算法分析 第七章 串、数组和广义表 作业讲解

     参考教材: 《数据结构(C语言版 第2版)》 严蔚敏,李冬梅,吴伟民编著,人民邮电出版社,2022年版。 截图未标明出处均为原创或取自《数据结构(C语言版 第2版)》~   本文对应的作业题讲解视频:   数据结构与算法分析作业讲解视频合集 https://www.bilibili.com/video/BV1N

    2024年02月04日
    浏览(46)
  • go 笔记 第七章 golang 的函数 func 方法

    声明函数 func 函数名(入参1 类型, 入参2 类型,… )(出参1 类型, 出参2 类型…){ 函数体,写逻辑 出参一定要全部 return, return 出参 } 函数内部不可以声明带名字的函数,可以声明匿名函数和自执行函数 函数名大写可以被其他包调用,小写私有,变量名也是一样 return 后面可以不

    2024年02月15日
    浏览(42)
  • golang返回多层结构数据

    正常情况下,查询出的结果,基本上都是结构体所得 如图所表示,基本上查询出的两个结果 返回结果 比较好的办法是,data1和data2和data3等多个都包含在一个data里面,然后这个data和msg,以及code同一层级,而不是data1和data2和data3这些和msg以及code同一层级 解决办法: 可以事先

    2024年01月22日
    浏览(36)
  • 数据结构 | 第七章:数组和矩阵 | 行主映射和列主映射 | 稀疏矩阵

    7.1.1 抽象数据类型 7.1.2 C++数组的索引 K维数组的索引(或下标) [ i 1 ] [ i 2 ] [ i 3 ] . . . [ i k ] [i_1][i_2][i_3]...[i_k] [ i 1 ​ ] [ i 2 ​ ] [ i 3 ​ ] ... [ i k ​ ] k维数组创建: int score [ u 1 ] [ u 2 ] [ u 3 ] . . . [ u k ] [u_1][u_2][u_3]...[u_k] [ u 1 ​ ] [ u 2 ​ ] [ u 3 ​ ] ... [ u k ​ ] ( u i u_i u i ​

    2024年01月16日
    浏览(47)
  • 【数据结构】Golang 实现单链表

    通过指针将一组零散的内存块串联在一起 , 把内存块称为链表的“ 结点 ”。 记录下个结点地址的指针叫作 后继指针 next ,第一个结点叫作 头结点 ,把最后一个结点叫作 尾结点 。 定义单链表 在 golang 中可以通过结构体定义单链表: 操作单链表 使用 golang 实现单链表常用

    2024年02月10日
    浏览(40)
  • 【夜深人静学数据结构与算法 | 第七篇】时间复杂度与空间复杂度

    前言:  引入:  时间复杂度:  案例: 空间复杂度: 案例: TIPS:        总结:         今天我们将来介绍时间复杂度和空间复杂度,我们代码的优劣就是依靠这个在评判,以此为背景,我们诞生出了不少的经典思路:用时间换空间,用空间换取时间。而大多数同学

    2024年02月10日
    浏览(62)
  • 【Golang】实现简单队列(Queue)数据结构

     在计算机科学中,队列是一种特殊的线性数据结构,它遵循FIFO(先进先出)原则。队列中的元素只能从一端(称为队尾或后端)添加,并且只能从另一端(称为队头或前端)移除。这种特性使得队列在许多算法和数据结构中都有广泛的应用,例如操作系统中的任务调度、网

    2024年01月19日
    浏览(37)
  • 数据结构 in Golang:Hash Tables(哈希表)

    水果店的价格表: 苹果 Apple:3元 香蕉 Banana:4元 桃子 Peach:2元 梨 Pear:3元 找到一种水果的价格: 可以使用 binary search,通过名称来查找,耗时:O(logn) 如何只耗时 O(1) 来找到价格呢? Hash 函数:通过一个字符串 - 一个数值 例如: \\\"Apple\\\" - 1 \\\"Banana\\\" - 2 \\\"Peach\\\" - 7 \\\"Pear\\\" - 8 将字符

    2024年02月08日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包