slice

基础的内存模型:

  • 传入一个slice占用24字节,分别是ptr、len和cap,分别一个字节。
  • append会再slice后面追加元素,具体参考代码1
    • cap没满的情况下,直接在后面的内存上追加数据。如果其它slice也有引用后面的内容,则相应的内容也会发生变化,因为内存是共享的。
    • cap满的情况下,会新开辟两倍的内存,把现有的数据复制进去,然后在新内存上追加数据
  • 如果要在函数内部对参数的slice追加元素,改变原来的slice,则要传切片指针,保证操作成功。。更好的方式是,只要涉及到更改传入切片的操作,都要返回新的切片,而不是传指针。参考代码2。
  • slice不是并发安全的

代码1

package main
import "fmt"
func main() {s := []int{0, 1, 2, 3, 4}s1 := s[1:3]fmt.Println(&s[1], len(s), cap(s), &s1[0], len(s), cap(s1))s1 = append(s1, 1)fmt.Println(&s[1], len(s), cap(s), &s1[0], len(s), cap(s1))fmt.Println(s)fmt.Println(s1)s = append(s, 5)fmt.Println(&s[1], len(s), cap(s), &s1[0], len(s), cap(s1))var ls []int // 仅仅是声明了一个变量fmt.Println(cap(ls), len(ls))for i := 0; i < 5; i++ {ls = append(ls, i)fmt.Println(&ls[0], len(ls), cap(ls))}
}

结果输出:

0xc000096038 5 5 0xc000096038 5 4  # 首地址不变,容量一直到结尾;两者共享内存
0xc000096038 5 5 0xc000096038 5 4  # 没超过cap的追加,只改变值
[0 1 2 1 4]  # 两者是共享内存的
[1 2 1]
0xc0000ae008 6 10 0xc000096038 6 4 #  s的容量不够了,开辟新的内存,copy数据后在追加,两倍扩容
0 0  // 声明的变量没有数据
0xc0000a20b0 1 1  // 每次扩容两倍
0xc0000a20d0 2 2
0xc0000a8020 3 4
0xc0000a8020 4 4
0xc0000aa040 5 8

代码2


package main
import "fmt"
func foo(ls []int) {ls = append(ls, ls...)
}
func fooP(ls *[]int) {  // 注意传指针*ls = append(*ls, *ls...)
}
func fooR(ls []int) []int {ls = append(ls, ls...)return ls
}
func main() {ls := []int{0, 1, 2, 3, 4}foo(ls) // 无法改变lsfmt.Println(ls)fooP(&ls)  // 传指针fmt.Println(ls)ls = fooR(ls) // 更推荐到方式fmt.Println(ls)
}

代码输出:

[0 1 2 3 4]
[0 1 2 3 4 0 1 2 3 4]
[0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4]

map

map的结构如下:

type hmap struct {count     int    // 元素的个数flags     uint8  // 状态标志B         uint8  // 可以最多容纳 6.5 * 2 ^ B 个元素,6.5为装载因子noverflow uint16 // 溢出的个数hash0     uint32 // 哈希种子buckets    unsafe.Pointer // 桶的地址oldbuckets unsafe.Pointer // 旧桶的地址,用于扩容nevacuate  uintptr        // 搬迁进度,小于nevacuate的已经搬迁overflow *[2]*[]*bmap
}

在Golang中,是没有传递引用的概念的,因此都是传值的。Map可以理解为“引用”,因为在赋值的时候,是赋值的存放实际数据的指针地址,因此新旧数据都是使用相同的指针地址的

赋值不同的确定值Map的时候,只有一个方式,即:

for k, v := range oldMap {newMap[k] = v
}

如果map的内容是interface{}类型,即k对应的v是不确定的,可以使用递归的方式:

package mainimport "fmt"func CopyMap(m map[string]interface{}) map[string]interface{} {cp := make(map[string]interface{})for k, v := range m {vm, ok := v.(map[string]interface{})  // 断言递归的方式if ok {cp[k] = CopyMap(vm)} else {cp[k] = v}}return cp
}func main() {mp := make(map[string]interface{})mp["1"] = 123mp["2"] = "foo"mp["3"] = map[string]string{"fooK": "456",}mp["4"] = map[string]interface{}{"foo-4": "777","foo-5": 987,"foo-6": map[string]string{"foo-61": "sddsd",},}newMp := CopyMap(mp)fmt.Println(newMp)
}

slice和map的高级主题相关推荐

  1. Redis 高级主题之布隆过滤器(BloomFilter)

    最近计划准备整理几篇关于Reids高级主题的博文,本文整理的是关于布隆过滤器在Redis中如何应用,先来一张思维导图浏览全文. 1. 认识BloomFilter 1.1 原理 布隆过滤器,英文叫Blo ...

  2. Spread for Windows Forms高级主题(3)---单元格的编辑模式

    理解单元格的编辑模式 通常情况下,当终端用户双击单元格时,编辑控件将允许用户在该单元格中输入内容.在一个单元格中编辑的能力被称为编辑模式.一些属性和方法可以用来自定义编辑模式的使用. 当一个单元格处于 ...

  3. Spread for Windows Forms高级主题(5)---数据处理

    2019独角兽企业重金招聘Python工程师标准>>> 使用表单的API处理数据 你可以将数据以有格式或无格式字符串或者数据对象的形式填充到单元格中.将数据填充到单元格的最好方式取决 ...

  4. Spread for Windows Forms高级主题(7)---自定义打印的外观

    2019独角兽企业重金招聘Python工程师标准>>> 表单打印的多个部分都可以进行自定义,大多数的自定义选项存在于PrintInfo对象中.大多数打印选项是在PrintInfo对象 ...

  5. 分享21款漂亮的WordPress高级主题

     WordPress 是最流行的博客系统,各种主题非常多,其中很多的高级主题(Premium Theme)都是要付费购买的,今天本文收集到21款免费的 WordPress 高级主题分享给大家. Bol ...

  6. Spread for Windows Forms高级主题(6)---数据绑定管理

    自定义列和区域的数据绑定 当表单被绑定到一个数据集时,表单中的列就会相继的被分配到数据集的区域上.例如,第一个数据域分配给列A,第二个数据区域分配给列B,等等.你也可以改变分配顺序,将任意域分配给任意 ...

  7. Spread for Windows Forms高级主题(4)---自定义用户交互

    你可以从多方面自定义用户界面来自定义用户与Spread控件的交互方式.同时,你还可以自定义如何处理用户交互方式. 设置允许用户进行的操作 下面的列表总结了通过控件的数据区域,你可以授权用户进行的操作( ...

  8. Go语言的复合数据类型struct,array,slice,map

    1.结构体 struct 定义格式: type 结构体名称 struct {属性1 类型属性2 类型... } 结构体的初始化可以使用new关键词和var关键词,不同的是如果使用new,则返回类型是一 ...

  9. android开发笔记之高级主题—传感器的简单介绍

    今天我们开始进入讲解android中的一些高级主题的用法,比如传感器.GPS.NFC.语音和人脸识别等. 这次来对传感器的一个简单介绍: Android平台支持三大类的传感器: 位移传感器 这些传感器 ...

最新文章

  1. mysql数据没有真正提交,转MySQL 批量提交优化
  2. excel求期望_商务数据分析考试:决策树分析(Excel)-安聪
  3. es6 name属性
  4. yii框架安装及环境配置!!!
  5. angularjs 获取复选框的值_哈迪斯仙酒有什么用 哈迪斯仙酒获取方式以及作用一览...
  6. 为现有的表添加自增列id并赋值
  7. DoNet 高效开发必备开发工具
  8. Apache Payara:让我们加密
  9. 拼图推迟将Java 9的发布日期推迟到2017年
  10. 95-38-050-Buffer-UnpooledHeapByteBuf
  11. 使用EL表达式,显示Action中的数据
  12. caj文件浏览器_史上最全:提高律师工作效率必不可少的27款浏览器插件
  13. spring整合大全
  14. 逻辑运算符 用法解释
  15. Web2.0创业者面临艰难选择:出售还是发展
  16. linux内存源码分析 - 伙伴系统(初始化和申请页框)
  17. ListView嵌套ListView优化
  18. Perl语言入门(05 文件)
  19. 基于C++和AStar算法求解八数码问题的方案
  20. 利用python、selenium和超级鹰 实现B站自动登录

热门文章

  1. 递归求解全排列问题以及八皇后问题
  2. 数据结构 2-3-3 循环链表
  3. LeetCode 58.最后一个单词的长度(python、c++)
  4. 01背包问题-一维数组实现原理
  5. 目标检测——Detectron2的学习笔记
  6. 彻底理解Python切片
  7. Altium AD20更改原理图的连接节点颜色和连线颜色(结点颜色)
  8. VScode设置console.log('')快捷键
  9. SpringBoot集成MyBatis详解
  10. 如何打造139团队(不同层次人员的选择与培养,大型研发团队,大型敏捷开发团队)...