golang中的切片
1. 切片中追加数据,如果没有扩容,内存地址不发生变化
// 1. 切片中追加数据,如果不扩容的话,内存地址不发生变化
v1 := make([]int, 1, 3)
v2 := append(v1, 55)
fmt.Println(v1, v2)
fmt.Printf("%p, %p\n", &v1[0], &v2[0])
v1[0] = 999
fmt.Println(v1, v2)
fmt.Printf("%p, %p\n", &v1[0], &v2[0]) // 有一个切片,请往切片中追加一个数据
v3 := make([]int, 1, 3)
v3 = append(v3, 999)
fmt.Println(v3)
2. 切片中追加数据,如果需要扩容的话,内存中就会拷贝一份出来,内存地址也就发生了变化
注意:扩容前和扩容后内存地址是不同的。
3. 切片中的常见操作
package main import (
"fmt"
"reflect"
) func main() {
// 1. 长度和容量
v1 := []int{11, 22, 33}
fmt.Println(len(v1), cap(v1)) //2. 索引
s1 := []string{"alex", "李杰", "老男孩"}
fmt.Println(s1[0], s1[1], s1[2])
s2 := make([]int, 2, 5)
fmt.Println(s2[0], s2[1])
s2[0] = 999
fmt.Println(s2) // 3. 切片,通过切片切出来的数据和原切片内部存储的数据地址相同
v2 := []int{11, 22, 33, 44, 55, 66}
v3 := v2[1:3]
fmt.Println(v3, reflect.TypeOf(v3))
fmt.Printf("%p,%p\n", &v2[1], &v3[0])
fmt.Printf("%p,%p\n", &v2[2], &v3[1]) // 4. 追加
v4 := []int{11, 22, 33}
v5 := append(v4, 999, 888, 777) // 扩容了
fmt.Println(v4, v5, cap(v5))
v5 = append(v5, []int{66, 55}...) // append第二个参数可以放一个切片
fmt.Println(v5, cap(v5)) // 5. 删除
v6 := []int{11, 22, 33, 44, 55, 66}
deleteIndex := 2
result := append(v6[:deleteIndex], v6[deleteIndex+1:]...)
// [11 22 44 55 66 66] [11 22 44 55 66]
fmt.Println(v6, result)
fmt.Println(len(v6), cap(v6), len(result), cap(result))
// 使用切片时不太会使用删除。1. 效率低 2. 修改了原切片的值, 建议使用链表
// 删除方式2:不修改原来切片的值,重新声明一个切片
//ret2 := make([]int, 0, len(v6)-1)
//ret2 = append(ret2, v6[:deleteIndex]...)
//ret2 = append(ret2, v6[deleteIndex+1:]...)
//fmt.Println(v6, ret2)
//fmt.Printf("%p,%p\n", &v6[0], &ret2[0]) // 6. 插入
v7 := []int{11, 22, 33, 44, 55, 66}
insertIndex := 3 // 在索引3的位置插入99
result1 := make([]int, 0, len(v7)+1)
result1 = append(result1, v7[:insertIndex]...)
result1 = append(result1, 99)
result1 = append(result1, v7[insertIndex:]...)
fmt.Println(v7)
fmt.Println(result1)
fmt.Printf("%p,%p\n", &v7[0], &result1[0])
// 注意:效率低下,建议使用链表 // 7. 循环
v8 := []int{11, 22, 33, 44, 55, 66}
for i, v := range v8 {
fmt.Println(i, v)
} }
4. 嵌套
v1 := [][]int{{11, 222, 88, 99}, {33, 44}}
fmt.Println(v1)
v2 := [][2]int{{11, 22}, {33, 44}, {55, 66}}
fmt.Println(v2) v1[0][3] = 1111
fmt.Println(v1)
v2[1][1] = 4444
fmt.Println(v2)
5. 变量赋值到底赋值数据吗?
(1)不可修改类型
// 整型,数据复制了一份
v1 := 1
v2 := v1
fmt.Printf("%p, %p\n", &v1, &v2) // 布尔,数据复制了一份
b1 := false
b2 := b1
fmt.Printf("%p, %p\n", &b1, &b2) // 浮点型,数据复制了一份
f1 := 3.14
f2 := f1
fmt.Printf("%p, %p\n", &f1, &f2) // 字符串型,数据复制了一份
// 只是复制了字符串的长度和指针地址,而并没有复制字符串本身的数据
// 同时:字符串内部元素是不可被修改的
s1 := "武沛齐"
s2 := s1
fmt.Printf("%p, %p\n", &s1, &s2)
// 数组,数据复制了一份
v1 := [2]int{6, 9}
v2 := v1
fmt.Printf("%p, %p\n", &v1, &v2)
fmt.Println(&v1[0], &v2[0])
(2)可变类型
// 切片,数组不会复制,复制的只是切片的内存地址
v1 := []int{6, 9}
v2 := v1
fmt.Printf("%p, %p\n", &v1, &v2)
fmt.Println(&v1[0], &v2[0]) // 0xc0000aa070 0xc0000aa070 // 如果扩容,那么内部存储数据的数组就会重新开辟区域
v1 = append(v1, 999)
fmt.Println(v1, v2)
fmt.Println(&v1[0], &v2[0]) // 0xc0000a8080 0xc0000aa070
总结:目前所学的所有数据类型中,在修改切片的内部元素时,会造成所有的赋值的变量同时修改(不扩容)
扩展:"引用类型和值类型",官方不建议这么说,如果这样理解的话:切片是引用类型,整型、布尔、浮点型、字符串、数组都是值类型。
6. 切片练习题
package main import "fmt" func main() {
// 嵌套1
v1 := [][]int{make([]int, 2, 5), make([]int, 2, 5)}
v2 := append(v1[0], 99)
v2[0] = 69
fmt.Println(v1) // [[69 0], [0 0]]
fmt.Println(v2) // [69 0 99]
// 嵌套2
//v1 := [][]int{make([]int, 2, 5), make([]int, 2, 5)}
//v2 := append(v1[0][1:], 99)
//v2[0] = 69
//
//fmt.Println(v1) // [[0, 69], [0, 0]]
//fmt.Println(v2) // [69 99] }
7. 切片和数组的区别?
(1)切片使用变量赋值的时候,两个切片变量使用的是同一块数据内存,而数组使用变量赋值的时候,两个数组变量使用的是不同内存
(2)数组是定长的,而切片是可变长的动态数组,而且切片定义时可以指定长度和容量
8. new和make的却别?
(1)new返回的是一个指针,而make返回的是一个对象
(2)new也帮助我们进行了初始化,整型初始化值是0,而make在它的内部也可以设置默认长度和默认容量。
golang中的切片的更多相关文章
- golang数组与切片
golang中坑的慢慢踩! golang中的数组是值类型,函数调用是传入的是数组的拷贝,如果想改变数组的值,可考虑使用指针数组,即函数调用时传入数组的地址 golang中的切片是引用类型,但是在函数中 ...
- Golang中的Slice与数组
1.Golang中的数组 数组是一种具有固定长度的基本数据结构,在golang中与C语言一样数组一旦创建了它的长度就不允许改变,数组的空余位置用0填补,不允许数组越界. 数组的一些基本操作: 1.创建 ...
- Golang中的坑二
Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...
- golang 中的指针
# golang 中的指针 看了一篇[文章](http://blog.51cto.com/steed/2341409),写的很好.这里略微总结下重点: 1. 地址值.unsafe.Pointer.ui ...
- GoLang基础数据类型-切片(slice)详解
GoLang基础数据类型-切片(slice)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数 ...
- Golang 中哪些值是不可以寻址的
不可以寻址, 指的是不能通过&获得其地址. golang中不能寻址的可以总结为:不可变的,临时结果和不安全的.只要符合其中任何一个条件,它就是不可以寻址的. 具体为: 常量的值. 基本类型值的 ...
- 七、golang中接口、反射
一.接口定义 1.定义 interface类型可以定义一组方法,但是这些不需要实现,并且interface不能包含任何变量 package main import ( "fmt" ...
- golang中的左值VS右值
对应关系 左值 可寻址 右值 不可寻址 可寻址:可以通过&取地址符,获取内存地址; 可寻址,也就是分配了内存; 不可寻址:根本没有分配内存; 常量const 常量通常只支持数字/字符串/布尔, ...
- golang中的RPC开发-2
RPC简介 远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程 如果 ...
随机推荐
- SQL注入绕过
空格字符绕过 %09 TAB建(水平) %0a 新建一行,换行 %0b TAB建(垂直) %0c 新的一页 %0d return 功能 %a0 空格 %00 /**/ /*!*/./*!50009*/ ...
- SpringBoot简单整合Actuator监控
pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s ...
- java源码——计算不同图形的周长和面积
计算任意三角形,正方形,正五边形,圆形的周长和面积. 利用类的继承实现. 将计算结果进行输出. 不多说,贴码. Contants.java 常量存储类 <pre name="code& ...
- 【LeetCode】800. Similar RGB Color 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...
- 【LeetCode】434. Number of Segments in a String 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计 正则表达式 字符串分割 日期 题目地址:htt ...
- (数据科学学习手札133)利用geopandas绘制拓扑着色地图
本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 我们在绘制某些地图时,为了凸显出每个独立的 ...
- WPF中的StaticResource和DynamicResource有什么区别
StaticResource 是静态资源 DynamicResource是动态资源 用一下例子说明 <Window.Resources> <Style x:Key="Bor ...
- Latex 入门教程
Latex 入门教程 学习途径:LaTex入门_哔哩哔哩_bilibili 运行环境:texlive2021.texstudio-4.1.2-win-qt6 1. 基本结构 整个 Latex 文件分为 ...
- [opencv]图像预处理方案及方式
像识别中,图像质量的好坏直接影响识别算法的设计与效果精度,那么除了能在算法上的优化外,预处理技术在整个项目中占有很重要的因素,然而人们往往忽略这一点. 图像预处理,将每一个文字图像分检出来交给识别模块 ...
- Java实习生常规技术面试题每日十题Java基础(六)
目录 1.在Java语言,怎么理解goto. 2.请描述一下Java 5有哪些新特性? 3.Java 6新特性有哪些. 4.Java 7 新特性有哪些. 5.Java 8 新特性有哪些. 6.描述Ja ...