Golang学习——string和slice切片

string

整数存储

在这里插入图片描述

  • 1个字节可以表示256个数字,2个字节可以表示65536个数字

字符存储

  • 字符集:字符编号对照表。收录很多数字,给它们一一编号。
    在这里插入图片描述
  • 字符集的更迭
    在这里插入图片描述
  • 全球化统一标准——通用字符集

Unicode

  • 于1990年开始研发并于1994年正式公布,实现了跨语言跨平台的文本转换与处理。
  • 字符集促成了字符与二进制的合作。但不是万事大吉:如何存储?

存储

  • 存储的歧义
    在这里插入图片描述
  • 字符边界解决:定长编码,位数不够高位补零。
    在这里插入图片描述
  • 缺点:浪费内存。

变长编码规则

  • 在这里插入图片描述
  • 解码的过程
    在这里插入图片描述
  • 编码的过程
    在这里插入图片描述
  • UTF-8是GO语言默认的编码方式:字符集配合编码

字符串类型变量的结构

  • 变量:起始地址。在内容结尾处放特定标识符。
  • c语言使用字符编号为0的字符。(字符串内容不能出现这个标识符)
  • GO语言并没有采取相同方式,而是在起始地址后面多存一个长度,长度为字节个数。
    在这里插入图片描述
  • 可读取不能修改
  • 原因:Go语言认为字符串内容是不会被修改的。会将定义的字符串内容分配到只读内存段。内存中的读、写、执行权限是为了保护程序正常运行。
  • 字符串变量是可以共用底层字符串内容的。

字符串变量的修改方式

  • 1.可以直接给变量整体赋新值,它存储的地址就会指向新的内容,并没有去“修改”原来的内存。
    在这里插入图片描述
  • 2.也可以把变量强制类型转换成字节slice,
    在这里插入图片描述
  • 这样会为slice变量重新分配一段内存,并且会拷贝原来字符串的内容,同样可以脱离只读内存的限制。

slice

  • 元素存哪里,存了多少个元素,可以存多少个元素。
    在这里插入图片描述
  • 声明一个整型slice,变量ints由这样三个部分组成。
    在这里插入图片描述
  • slice的元素要存在一段连续的内存中
    在这里插入图片描述
  • data就是这个底层数组的起始地址,但因只分配了切片结构,所以为nil。
  • 存储元素个数为0,容量也为0。

通过make的方式定义变量

  • 不仅会分配这三部分结构,还会开辟一段内存作为它的底层数组。
    在这里插入图片描述
  • make会为ints开辟一端容纳5个整型元素的内存,还会把它们初始化为整型的默认值0,但是目前这个slice只存储了两个元素。
    在这里插入图片描述

new

  • new一个slice变量,同样会分配三部分结构,但它不负责底层数组的分配。data=nil。
  • new的返回值就是slice结构的起始地址。
    在这里插入图片描述
  • 此时,这样的slice变量还没有底层数组。
  • append用来分配底层数组。
  • 通过append的方式添加元素,它就会给slice开辟底层数组。
    在这里插入图片描述

底层数组

  • 数组:同种类型的元素一个挨一个的存储。
  • int型slice
    在这里插入图片描述
  • string型slice
    在这里插入图片描述
  • 是什么,底层就是什么数组。
  • 不一定指向数组开头。
  • 数组容量声明了就不能改变在这里插入图片描述
  • s1:1,2,3,左闭右开,从1开始,容量为9;
  • s2:7,8,9,容量也为3;
  • 索引左边决定容量,右边决定长度。
  • 给s1扩大访问元素
    在这里插入图片描述
  • 给s2添加元素(copy,注意容量到2倍)在这里插入图片描述

slice扩容规则

1.预估扩容后的容量newCap

在这里插入图片描述

  • 非固定1.25

2.newCap个元素需多大内存

  • NO在这里插入图片描述
  • 在许多编程语言中,申请分配内存,并不是直接与操作系统交涉,而是和语言自身实现的内存管理模块,它会提前向操作系统申请一批内存,分成常用的规格管理起来。待申请内存时,会帮助我们匹配到足够大且最接近的规格。

3.匹配到合适的内存规格

  • 5*8=40,实际:匹配到48字节。
  • 48/8=6个

练习

  • 16 bytes=8 bytes(指针8个字节)+8 bytes(len,Go中64位机器下Int占8个字节)
  • 多出来的是字节长度占的内存
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 golang 学习笔记,希望对你有帮助: ### 1. 基本语法 - 包声明:每个 Go 程序都是由多个包组成,使用 `package` 声明包名。 - 引入包:使用 `import` 关键字引入需要的包。 - 函数:使用 `func` 关键字声明函数,函数可以有多个返回值。 - 变量:使用 `var` 关键字声明变量。 - 常量:使用 `const` 关键字声明常量。 - 控制语句:Go 语言支持条件语句和循环语句,例如 `if`、`switch`、`for` 等。 ### 2. 数据类型 Go 语言支持以下数据类型: - 布尔型:`bool` - 数字类型:`int`、`int8`、`int16`、`int32`、`int64`、`uint`、`uint8`、`uint16`、`uint32`、`uint64`、`uintptr`、`float32`、`float64`、`complex64`、`complex128` - 字符串类型:`string` - 派生类型:`array`、`slice`、`map`、`struct`、`interface`、`channel` ### 3. 函数 Go 语言中的函数可以有多个返回值,可以使用命名返回值来使函数更加清晰易读。例如: ```go func swap(x, y string) (string, string) { return y, x } ``` ### 4. 数组和切片 Go 语言中的数组和切片都是支持多维的。数组和切片的区别在于数组长度是固定的,而切片长度可以动态变化。例如: ```go // 声明数组 var a [5]int // 声明切片 var s []int s = append(s, 1, 2, 3) ``` ### 5. 结构体 结构体是一种自定义的数据类型,可以包含多个不同类型的字段。例如: ```go type person struct { name string age int } func main() { p := person{"Bob", 20} fmt.Println(p.name, p.age) } ``` ### 6. 接口 接口定义了一组方法的集合,只要某个类型实现了接口中定义的所有方法,就可以认为它实现了这个接口。例如: ```go type Shape interface { area() float64 } type Circle struct { x, y, r float64 } func (c Circle) area() float64 { return math.Pi * c.r * c.r } func main() { var s Shape s = Circle{x: 0, y: 0, r: 5} fmt.Println(s.area()) } ``` ### 7. 并发 Go 语言使用协程来实现并发,协程是一种轻量级的线程,可以在一个线程中同时执行多个协程。例如: ```go func main() { go say("world") say("hello") } func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } ``` 以上就是 golang 学习笔记的主要内容,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值