当前位置: 首页 > news >正文

Go 语言基础1 Slice,map,string

更多个人笔记见:
github个人笔记仓库
gitee 个人笔记仓库
个人学习,学习过程中还会不断补充~ (后续会更新在github上)

文章目录

  • stirng 字符串
    • 区分 rune,byte,string
    • 字符串操作
        • strings 库相关
    • fmt.Printf语法
  • Slice 切片
        • 基础知识
            • 数组和切片的区别
        • append函数
            • 通过append看切片和扩容
            • 通过 append 合并切片
        • 利用\[:]的方式制造切片
            • 截取示范
            • 截取的地址分析
        • := 赋值的影响
        • range 的使用
            • copy的使用
  • Map映射
        • 基本示例
        • map在并发读写中的问题
        • Map原理
            • map 结构

stirng 字符串

  • 求长度还是utf库中求,因为中文有占3/4字节的,用len不准确
  • 符串和数组不能直接123 + “456”这样拼接
    	con := fmt.Sprintf("123%d",456)println(con)
    

区分 rune,byte,string

package mainimport ("fmt"
)func main() {s := "hello world" //直接字符串形式for _, v := range s {fmt.Printf("value is %c,type is %T\n", v, v)//typeis:int32value (rune)}for _, v := range s {fmt.Println(v)  //是 int32 形式的数字//is int32vlaue (rune)fmt.Println(string(v))//string}tokens := []string{"2", "1", "+", "3", "*"} //用 string处理for i := 0; i < len(tokens); i++ {fmt.Printf("type is %T\n", tokens[i])//type is string}bytes := []byte("hello world")  //用 byte 处理for i := 0; i < len(bytes); i++ {fmt.Printf("value is %c,type is %T", bytes[i], bytes[i])//type is uint8fmt.Println(bytes[i])//value is 104,type is uint8}runes := []rune(s)for i := 0; i < len(runes); i++ {fmt.Printf("value is %c,type is %T\n", runes[i], runes[i])//value is h,type is runefmt.Println(string(runes[i]))//string}
}

总结:

  • 原始字符串之中 的内容每一个是 rune 存储,rune 是 int32
  • byte 就是转为 int8
  • string类型是不同于 rune 的,stirng 的列表中的类型就是 string 而不是 rune 的 int32

字符串操作

strings 库相关

常用:

func main() {fmt.Println(strings.ToUpper("hello"))fmt.Println(strings.ToLower("HELLO"))fmt.Println(strings.Replace("hello world", "world", "go", -1)) //hello gofmt.Println(strings.Split("hel-lo-w-rld", "-"))  //[hel lo w rld]fmt.Println(strings.Join([]string{"hel", "lo", "w", "rld"}, "-")) //hel-lo-w-rld
}

fmt.Printf语法

//输出形式
fmt.Printf("整数:%d\n", 123)      // %d:十进制整数
fmt.Printf("字符:%c\n", 'A')      // %c:字符
fmt.Printf("字符串:%s\n", "hello") // %s:字符串
fmt.Printf("布尔值:%t\n", true)    // %t:布尔值
fmt.Printf("浮点数:%f\n", 3.14)    // %f:浮点数
fmt.Printf("二进制:%b\n", 15)      // %b:二进制
fmt.Printf("十六进制:%x\n", 15)    // %x:十六进制(小写) //类型相关
fmt.Printf("类型:%T\n", 123)       // %T:类型
fmt.Printf("值:%v\n", 123)         // %v:默认格式
fmt.Printf("Go语法:%#v\n", "hello") // %#v:Go语法格式
fmt.Printf("p=%+v\n", p) // p={x:1 y:2} 打印结构体字段和名
fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2} 打印更具体结构体名称

Println 会自动回车,Printf 需要\n

Slice 切片

切片:定义,切片长度(实际大小len),容量(底层数组大小cap) 三个组成

基础知识
  • []中有数字就是数组,没有就是切片! (牢记)
    • []int{1,2,3}就是切片
  • 通常利用make()进行创建 如果使用{}就是直接书写数组内容
  • []中不可以是变量比如 k ,后面这样可以:[…] int {1,2,3,4} / [5] int {1,2,3,4,5}
  • make 初始化的时候如果只指定一个参数,那么就是切片长度=容量 这样初始化 注意只要是初始化的,都会用 0 占位!!
  • 理解res := []int{} 或者 var res []int 或者 res := make([]int,0) 不同的创建方式,经常还是用 make 更加直观
数组和切片的区别

array:数组 (不过变量命名无所谓) slice:切片
![[…/…/attachments/Pasted image 20250525104949.png]]
基本用的都是切片

append函数
通过append看切片和扩容
  • 不能直接使用索引来突破切片的长度限制
	func main() {a := make([]int, 5, 10) //长度a = append(a, 1, 2, 3,4)fmt.Printf("追加后切片长度为:%d,容量为:%d\n", len(a), cap(a))fmt.Println(a[0:5])fmt.Printf("追加后赋值的切片长度为:%d,容量为:%d\n", len(s1), cap(s1))fmt.Printf("追加后原来的切片长度为:%d,容量为:%d\n", len(a), cap(a))
}
//追加后切片长度为:9,容量为:10
//[0 0 0 0 0]
//追加后赋值的切片长度为:12,容量为:20 
//追加后原来的切片长度为:9,容量为:10
通过 append 合并切片
func main() {array := []int{1, 2, 3, 4, 5}array2 := []int{1, 2, 3, 4, 5}res := append(array,array2...) //需要加...fmt.Println(res)//[1 2 3 4 5 1 2 3 4 5]
}

算法中常用:

a := int(len(numbers)/2) //取出中间元素的位置
nunbers = append(numbers[:a],numbers[a+1:]...) //去掉这个个数
利用[:]的方式制造切片
截取示范
  • :后面的是不包括在里面的
    func main() {array := []int{1, 2, 3, 4, 5}s1 := array[:3]s2 := array[:]fmt.Println(s1, s2) // [1 2 3] [1 2 3 4 5]
    }
    
截取的地址分析
  • 二者地址上就差8个字节
func main() {array := []int{1, 2, 3, 4, 5}s1 := array[1:]fmt.Printf("array 切片地址%p\n",array) //不是 array 这个变量的地址,做好区分fmt.Printf("s1 切片地址%p\n",s1)fmt.Printf("array 变量地址%p\n",&array) //和上面切片地址是不一样的
}
:= 赋值的影响

赋值的操作本质上就是参数拷贝
利用:=来共享底层数组的切片,修改时会同时影响到

func main() {array := []int{1, 2, 3, 4, 5}s1 := arrays2 := array[1:3]array[0] = 100fmt.Println(s1)fmt.Println(s2)//[100 2 3 4 5]//[2 3]
}
range 的使用
func main() {nums := []int{2, 3, 4}sum := 0for _, num := range nums {sum += num}fmt.Println("sum:", sum)for i, num := range nums {if num == 3 {fmt.Println("index:", i)}//index: 1 }kvs := map[string]string{"a": "apple", "b": "banana"}for k, v := range kvs {fmt.Printf("%s -> %s\n", k, v)}//两个变量的时候传递的是key - valuefor k := range kvs {fmt.Println("key:", k)}//只有一个的时候,传递的是 keyfor i, c := range "go" {fmt.Println(i, c)}//0 103// 1 111   本质因为字符串之中是 int32 存储的}#### slice 相关库
######  slices.Equal(a,b)  return bool  判断是否相等
```Go
func main() {array := []int{1, 2, 3, 4, 5}s1 := arrayres:=slices.Equal(s1, array)fmt.Println(res) // Output: true
}

比较的时候不会看切片的 cap 是不是一样的,就是看 len 中的

copy的使用

有多少就 copy 多少,(,)从后面的 copy 到前面的

func main() {array := []int{1, 2, 3, 4, 5}s1 := make([]int, 6)s2:= make([]int, len(array))s3 := make([]int, 3)fmt.Println(len(s1), cap(s1)) // Output: 6,6copy(s1, array)copy(s2, array)copy(s3, array)fmt.Println(s1) // Output: [1 2 3 4 5 0]fmt.Println(s2) // Output: [1 2 3 4 5]fmt.Println(s3) // Output: [1 2 3]res := slices.Equal(s1, array)res2 := slices.Equal(s2, array)fmt.Println(res) // Output: falsefmt.Println(res2) // Output: true
}

Map映射

类似于 python 的字典

  • key和value 键-值的对应
    • var mapname map[keytype] valuetype 定义
基本示例
func main() {m := make(map[string]int)//map will auto increasem["k1"] = 7m["k2"] = 13fmt.Println("map:", m)v1 := m["k1"]fmt.Println("v1:", v1)v3 := m["k3"]fmt.Println("v3:", v3)fmt.Println("len:", len(m))delete(m, "k2")fmt.Println("map:", m)//delete certain keyclear(m)fmt.Println("map:", m)//clear all of the map_, prs := m["k2"]fmt.Println("prs:", prs)//return the value and indication about the key's existence//to disambiguate between missing keys and keys with zero values like 0 n := map[string]int{"foo": 1, "bar": 2}fmt.Println("map:", n)n2 := map[string]int{"foo": 1, "bar": 2}if maps.Equal(n, n2) {fmt.Println("n == n2")}
} 
map在并发读写中的问题
aa := make(map[int]int)go func (	for {// aa[0] = 5  //不可以的,不支持并发写_ = aa[2]   //可以的,读操作不影响写操作})()go func ()  {for {_ = aa[1]}}()
Map原理
map 结构

指定map长度为N,会初始化生成桶,桶数量为log2N
map在超过负载因子的时候会双倍重建,如果溢桶太大就会等量重建。当用到的时候旧桶才会放入新桶

相关文章:

  • 计算机视觉(图像算法工程师)学习路线
  • where is the examples of stm32h743i demo project inside of stm32cubeh7
  • 电商小程序店铺详情页:头部无限分类与筛选功能实现
  • 书生五期--端侧小模型论文分类微调打榜
  • 搭建 C/C++_CMake_Boost_git 开发环境
  • 计算机视觉中的可重复性:深入案例分析与Python代码实现
  • 【MySQL】08.视图
  • TiDB:从快速上手到核心原理与最佳实践
  • 【时时三省】(C语言基础)函数的嵌套调用
  • python学习day28
  • Linux 系统常用核心库----用户态程序运行的基石
  • 广东省省考备考(第二十天5.25)—言语:逻辑填空(听课后强化训练)
  • 前端常见的安全问题
  • java高级 -Junit单元测试
  • 用VMWare架飞牛nas 启用Intel千兆网卡
  • 基于点标注的弱监督目标检测方法研究
  • Linux Kernel调试:强大的printk(一)
  • 程序代码模块化设计的架构方法论
  • 《仿盒马》app开发技术分享-- 定位获取(端云一体)
  • LangChain02-Agent与Memory模块
  • 哪几个网站做acm题目比较好/百度如何优化
  • 成都网站建设定/沈阳高端关键词优化
  • 哈尔滨政府网站建设/app营销策略有哪些
  • wordpress 页面 html代码/柏乡seo快排优化
  • 企业网站seo数据/营销型制作网站公司
  • 柳州做网站价格/搜索引擎优化通常要注意的问题有