首页 > 其他分享 >go_切片

go_切片

时间:2024-04-07 18:44:20浏览次数:13  
标签:--- -- fmt s4 切片 Println go

切片

# 定义
切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用
数组定长,长度不能改变---》python中列表----》go切片


# 知识点
1 创建一个切片(通过数组创建)
    
2 使用 make 创建一个切片    
3 切片的修改
4 切片的长度和容量

5 追加切片元素
6 切片的函数传递
7 多维切片
8 内存优化
——————————————————————————————————
package main

import "fmt"

// 切片

func main() {
    // 1 创建一个切片(通过数组创建)
    var a [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    // 切片--->从a数组上,从0到结尾,切片赋值给s
    //var s = a[:]
    var s []int = a[:]
    fmt.Println(s)
    // 查看类型--->中括号中没有数字-->就是切片,有数字就是数组
    // 区分数组(值)和切片(引用)类型
    fmt.Printf("s的类型是:%T\n", s) // []int

    // 2 使用 make 创建一个切片-->必须通过make或通过数组切出来,否则是空的
    var s1 []string = make([]string, 4)
    fmt.Println(s1)

    // 3 切片零值
    // 3.1 通过数组切出来,不会为 空
    // 3.2 如果只定义,没有初始化--》零值---》空---》nil
    var s2 []string
    fmt.Println(s2) // []

    // 4 操作切片---》取值,赋值---》使用 [数字]
    s1[0] = "lqz"
    s1[1] = "彭于晏"
    fmt.Println(s1)
    s1[0] = "ssdfasdf"
    fmt.Println(s1)

    // 5 如果切片为  空,nil--》没有初始化 不能使用(取值赋值)

    s2 = make([]string, 1) // 不是nil了,但是长度为0
    if s2 == nil {         // python 的None
        fmt.Println("s2不能初始化,不能使用")
        return
    }
    s2[0] = "lqz" // s2没有初始化,报错  index out of range [0] with length 0
    fmt.Println(s2)

    // 使用切片 s1[0]---》报index out of range [0] with length 0--》两个原因:1 nil 2 长度不够

    // 6 切片的长度和容量
    // 长度:切片放了几个值
    // 容量:切片总共能放几个值
    var a1 [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    var s3 []int = a1[2:3]
    fmt.Println(s3)      // [6 7]  前闭后开区间
    fmt.Println(len(s3)) // len 长度 2
    fmt.Println(cap(s3)) // cap 容量 5 切片基于底层数组,容量取决于底层数组--》从切片起始位置到数组最后

    var s4 = make([]int, 2, 4)
    fmt.Println(len(s4)) // 2
    fmt.Println(cap(s4)) // 4

    // 7 追加切片元素
    // s4 长度是2,容量是4,还能追加俩值
    s4 = append(s4, 99) // 内置函数追加--->s4不是对象
    fmt.Println(s4)
    fmt.Println(len(s4)) // 3
    fmt.Println(cap(s4)) // 4
    s4 = append(s4, 88)  // 内置函数追加--->s4不是对象
    fmt.Println(s4)
    fmt.Println(len(s4)) // 4
    fmt.Println(cap(s4)) // 4
    // 超过容量,再追加---》不会报错---》
    s4 = append(s4, 77) // 内置函数追加--->s4不是对象
    fmt.Println(s4)
    fmt.Println(len(s4)) // 5
    fmt.Println(cap(s4)) // 8---》翻倍扩容

    s4 = append(s4, 66, 55, 44, 33) //
    fmt.Println(s4)
    fmt.Println(len(s4)) // 9
    fmt.Println(cap(s4)) // 16---》翻倍扩容

    s4 = append(s4, 22, 11, 12, 13, 11, 12) //
    fmt.Println(s4)
    fmt.Println(len(s4)) // 16
    fmt.Println(cap(s4)) // 16---》翻倍扩容-->32

    //8 切片的函数传递  切片是引用类型
    test001(s4)            // [0 0 99 88 77 66 55 44 33 22 11 12 13 11 12 13]
    fmt.Println("外部:", s4) // 函数内修改,会影响原来的值

    // 很深的坑: s4 长度和容量 都是16 当参数传到函数中,修改,会不会影响原来的?
    test002(s4)
    fmt.Println("外部:", s4) // 函数内修改,会影响原来的值
    /*
        1 因为切片依赖于底层数组
        2 底层数组的改变会影响切片,切片的改变也会影响底层数组
        3 当使用append追加上,如果超过了切片容量--》切片会扩容--》重新创建一个数组--》把原来的值复制过去--》容量翻倍了--》切片指向新的数组
        4 如果当参数传递,再函数中,使用append
            1 超过容量,只要超过后,再修改某个位置的值,就不会相互影响了
            2 如果没有超过容量,再修改某个位置的值,会相互影响了
    */

    // 9 多维切片
    var s5 [][]int = make([][]int, 2, 3)
    //s5[0]=1
    s5[0] = make([]int, 3) // 内层切片使用,也要初始化
    s5[0][0] = 99          // 报错了---》内层的切片,没有通过make初始化出来,不能用
    fmt.Println(s5)

    var s6 [][3]int = make([][3]int, 2, 3)
    fmt.Println(s6[0])
    s6[0][0] = 99
    fmt.Println(s6)

    // 多维切片,第n层,要不要初始化,取决于第n层是什么类型

    // 定义并赋初值
    var s7 [][]string = [][]string{{"lqz", "小红"}, {"asfd"}, {"111", "22", "333", "444"}}
    //var s7 [][4]string = [][4]string{{"lqz", "小红"}, {"asfd"}, {"111", "22", "333", "444"}}
    fmt.Println(s7[0][1])
    fmt.Println(len(s7[2])) // 1
    fmt.Println(cap(s7[2])) // 1
    //fmt.Println(s7[2][4])   // 越界了
    //fmt.Println(s7[0][2]) // 数组不会越界,切片就会越界
    s7[0] = append(s7[0], "中")
    fmt.Println(len(s7[0])) // 3
    fmt.Println(cap(s7[0])) // 4

    // 10 内存优化  copy函数
    var a3 [100]int
    fmt.Println(a3)
    var s8 []int = a3[0:3]
    fmt.Println(s8)
    s8[0] = 88
    fmt.Println(s8)
    fmt.Println(a3)
    a3[1] = 66
    fmt.Println(s8)
    fmt.Println(a3)

    //s8 拷贝到小一点的切片上(底层数组小)  ---》可以大可以小
    var s9 = make([]int, 5, 5)
    copy(s9, s8)
    fmt.Println(s9) // 长度和容量,都是3--》以后操作s9-->传参,修改---》底层数组只有3的大小---》内存空间占用小

}

func test001(s []int) {
    s[0] = 999
    fmt.Println(s)
}

func test002(s []int) {
    s[0] = 999
    fmt.Println(s)
    // 如果,再内部,append--——》追加--》超过容量--》放弃掉底层数组---》新创建一个新数组--》指向新数组
    s = append(s, 666)
    fmt.Println("内部", s)
    s[0] = 888
    fmt.Println("内部", s)

}

可变长参数

package main

import "fmt"

// 可变长参数
func main() {
    // *  ** 放在形参上
    // *:接收任意长度的位置参数
    // ** 接收任意长度的关键字参数

    // * ** 放在实参上--》* 只能放在列表上,  ** 只能放在字典上

    // go 只有按位置传参数---》没有按关键字这种用法
    test003(33, 44, "9")

    // 传任意长度参数
    //fmt.Println(1,2,3,4,5,"dafas")

    test004("11", "22", "14", "15", "16", "17", "18", "19")

    var ss1 [5]string = [5]string{"lqz", "彭于晏", "刘亦菲"}
    test004(ss1[:]...) // 打散了传入

    // 思考题
    welcome := []string{"hello", "world"} // 长度是2,容量是2
    //welcome := make([]string,3,4) //
    change(welcome...)   // 内部本质就是把 welcome 给了 s
    fmt.Println(welcome) // {"Go", "world"}
}

func test003(a, b int, c string) {
    fmt.Println(a, b, c)
}

func test004(a ...string) {
    fmt.Println(a) // 可以传任意长度字符串===>a是什么类型?字符串类型? 字符串切片类型 []string
    fmt.Printf("a的类型是:%T", a)
    //for i := 0; i < len(a); i++ {
    //    fmt.Println(a[i])
    //}

    for _, value := range a {
        fmt.Println(value)

    }
}

func change(s ...string) {
    s[0] = "Go"
    s = append(s, "playground")
    fmt.Println(s) // [Go world  playground]
    s[0] = "lqz"
    fmt.Println(s) // [lqz  world  playground]
}

map

# 数组,切片,map  容器类型

# map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值

如何创建 map
给 map 添加元素
获取 map 中的元素
删除 map 中的元素
获取 map 的长度
Map 是引用类型
Map 的相等性

hash冲突

# python中的字典 
# go中得map
# redis中得 hash
# java中得 HashMap,TreeMap

# 1  就是根据key即经过一个函数f(key)得到的结果的作为地址去存放当前的key value键值对(这个是hashmap的存值方式),但是却发现算出来的地址上已经有人先来了

就是相当于你在蹲坑,又有人进来了,但是只有一个坑,就产生了冲突,需要开辟新的空间去让另一个人有地方上厕所


# 2 解决hash冲突
    1 开放寻址法
        1.1  线性探测
        按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上往后加一个单位,直至不发生哈希冲突。
        就是在此空间不足时,直接放入此空间的后一个空的空间
        1.2 伪随机探测
            
        
    2 再哈希法(Rehashing):
        使用另一个哈希函数处理冲突
    
    3 链地址法(java的hashmap):
        - 对于相同的值,使用链表进行连接。使用数组存储每一个链表

    4 建立公共溢出区

 

标签:---,--,fmt,s4,切片,Println,go
From: https://www.cnblogs.com/wzh366/p/18119679

相关文章

  • 【22.0】Django框架之CBV添加装饰器的三种方式
    【一】引言给类视图函数添加装饰器需要借助第三方模块fromdjango.utils.decoratorsimportmethod_decorator【二】三种添加装饰器方式【1】给类方法加装饰器指名道姓的装--放在方法上面(1)路由path('login_view/',views.MyLogin.as_view()),(2)视图fromdjango.vi......
  • 【21.1】Django框架之会话Session补充
    【一】前言引入【1】HTTP特性之无状态因为因特网HTTP协议的特性,每一次来自于用户浏览器的请求(request)都是无状态的、独立的。通俗地说,就是无法保存用户状态,后台服务器根本就不知道当前请求和以前及以后请求是否来自同一用户。对于静态网站,这可能不是个问题,而对于动态网站,尤其......
  • 【21.0】Django框架之Cookie和Session
    【一】Cookie与Session的发展史Cookie和Session是用来在Web应用程序中跟踪用户会话数据的两种常用技术。【1】Cookie的发展史1994年,网景通信公司推出了第一个浏览器Cookie技术。Cookie是存储在用户计算机上的小型文本文件,用于跟踪用户在网站上的活动。初始版本的Cookie只......
  • 【24.0】Django框架之csrf跨站请求
    【一】跨站请求伪造介绍【1】引入CSRF(Cross-SiteRequestForgery)跨站请求伪造是一种常见的网络攻击方式。攻击者通过诱导受害者访问恶意网站或点击恶意链接将恶意请求发送到目标网站上利用受害者在目标网站中已登录的身份来执行某些操作从而达到攻击的目的。【2】举......
  • 【23.0】Django框架之中间件引入
    【一】Django中间件介绍【1】什么是Django中间件Django中间件是一个轻量级、可重用的组件,用于处理Django请求和响应的过程。它提供了对请求和响应进行全局处理的机制,可以在请求达到视图之前进行预处理或在响应返回给客户端之前进行后处理。中间件是按照顺序依次执行的,每......
  • 【26.1】Django框架之settings配置
    【一】引言Django项目的设置文件位于项目同名目录下,名叫settings.py。这个模块,集合了整个项目方方面面的设置属性,是项目启动和提供服务的根本保证。【二】简述settings.py文件本质上是一个Python模块,带有模块级别的变量。下面是一些示例设置:ALLOWED_HOSTS=['www.examp......
  • 【26.0】Django框架之settings源码
    【一】Django配置文件介绍Django框架默认提供给我们一个配置文件在我们项目根目录下的setting.py文件中,在里面我们可以看到很多的配置项并且我们能够自主的添加相应的配置但是其实这个文件只是Django暴露出来给我们的一个接口文件,在Django内部还存在一个更加强大的配置文件......
  • 【25.0】Django框架之auth模块
    【一】Auth模块引入我们在创建一个Django项目之后,直接执行数据库迁移命令会自动生成很多表django_sessionauth_userDjango在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且必须是管理员用户才能进入【二】创建超级用户(管理员)......
  • python计算机毕设【附源码】汉服文化管理系统(django+mysql+论文)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:汉服,作为中国古代汉族传统服饰的总称,承载了丰富的历史文化遗产和审美价值。近年来,随着国民文化自信心的提升和传统文化复兴的浪潮,汉服文化逐渐走进了公众的......
  • 【26.2】Django框架之settings核心配置项
    【一】前言【1】引言Django的默认配置文件中,包含上百条配置项目其中很多是我们‘一辈子’都不碰到或者不需要单独配置的这些项目在需要的时候再去查手册。【2】强调配置的默认值不是在settings.py文件中!不要以为settings.py中的配置值就是默认值,参考前文。settings.py......