go 创建slice的方式
1、直接声明:var slice []int
2、new: slice := *new([]int)
3、字面量:slice := []int{1,2,3,4,5}
4、make: slice := make([]int, 5, 10)
5、从切片或数组“截取”:slice := array[1:5] 或 slice := sourceSlice[1:5]
Golang Slice,以及append函数的陷阱:
slice并不是单纯的一个指向数组的指针,它是一个结构体(包含:指针,长度,容量)
先看一个小例子:
func main() {
a := make([]int, 2, 2)
a[0], a[1] = 1, 2
b := append(a[0:1], 3)
c := append(a[1:2], 4)
fmt.Println(b,c)
}
在这个小例子中,原本是希望将a[0:1]作为b的前缀,然后追加上3;将a[1:2]作为c的前缀,然后追加上4。
但实际上输出结果并不是原本期望的[1 3] [2 4],而变成了[1 3] [3 4]。这是为什么呢?
我们知道数据结构中数组是非常高效的,可以直接寻址,但是有个缺陷,难以扩容。所以slice被设计为指向数组的指针,
在需要扩容时,(会将底层数组上的值复制到一个更大的数组)上然后指向这个新数组。
slice有个特性是允许多个slice指向同一个底层数组,这是一个有用的特性,在很多场景下都能通过这个特性实现 no copy 而提高效率。
但共享同时意味着不安全。b在追加3时实际上覆盖了a[1],导致c变成了[3 4]。
怎么解决呢?防止共享数据的出现问题需要注意两条,只读和复制,或者统一归纳为不可变。
写法1,make出一个新slice,然后先copy前缀到新数组上再追加:
func main() {
a := make([]int, 2, 2)
a[0], a[1] = 1, 2
b := make([]int, 1)
copy(b, a[0:1])
b = append(b, 3)
c := make([]int, 1)
copy(c, a[1:2])
c = append(c, 4)
fmt.Println(b, c)
}
写法2,利用go中slice的一个小众语法,a[0:1:1] (源[起始index,终止index,cap终止index]),强迫追加时复制到新数组。
func main() {
a := make([]int, 2, 2)
a[0], a[1] = 1, 2
b := append(a[0:1:1], 3)
c := append(a[1:2:2], 4)
fmt.Println(b, c)
}
go 创建slice的方式的更多相关文章
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- Wireshark工具创建过滤器的方式
Wireshark工具创建过滤器的方式 [实例1-3]现在要抓取目的或来源地址为192.168.5.9的封包.在图1.5中添加如下所示的条件: tcp dst port 3128 添加后单击Star ...
- Java多线程学习总结--线程概述及创建线程的方式(1)
在Java开发中,多线程是很常用的,用得好的话,可以提高程序的性能. 首先先来看一下线程和进程的区别: 1,一个应用程序就是一个进程,一个进程中有一个或多个线程.一个进程至少要有一个主线程.线程可以看 ...
- JS面向对象编程创建类的方式
js创建类的方式有几种,大致如下: 1,构造函数方式: function Car(parameters) { this.name = "objectboy"; } var cat1 ...
- java中创建多线程的方式
在java中比较常用的有三种创建多线程的方式. 方式一:继承Thread类,要重写run方法. 在MyThread类 public class MyThread extends Thread { @O ...
- Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式
Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...
- 7. Callable 创建线程的方式三
package com.gf.demo06; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionEx ...
- Vue 创建组件的方式
Vue 创建组件的方式 2018年08月07日 11:10:56 虔诚带着决然 阅读数:1015 版权声明:本文为博主原创文章,未经博主允许不得用做其他商业活动. https://blog.csd ...
- @Scope注解设置创建bean的方式和生命周期
1.1.1 Scope注解创建bean的方式和生命周期 作用 Scope设置对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式. 取 ...
随机推荐
- 深入JVM内核--GC算法和种类
GC的概念 Garbage Collection 垃圾收集 1960年 List 使用了GC Java中,GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 使用者 CO ...
- Archives: 2018/11
There are 35 posts in total till now. 11月 11, 2018 HTTP 11月 11, 2018 TCP与UDP 11月 10, 2018 Python测试 1 ...
- SPA(单页面web应用)和MPA(多页面web应用)的区别
转:https://blog.csdn.net/amaniz/article/details/79203562 vue多页面应用开发请参见: https://github.com/amunamuna/ ...
- CPU|MICGPU|FPGA|超算|Meta-data|
生物医学大数据: 收集数据后对数据的分析,如同看相,而对数据信息的挖掘可以看作是算命.这两个过程是基于算法和软件这类工具之上的. 在存储方面:在硬件上,为了Parallel computing的目的, ...
- [洛谷P3366] [模板] 最小生成树
存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...
- python有关汉字编码问题
python分为:程序编码(python安装程序).文件编码. 查看程序编码方式:sys.getdefaultencoding() 查看文件编码方式:1.import chardet 2. f = ...
- SpringMVC之@SessionAttribute和@ModelAttribute
1.Controller package com.tz.controller; import java.util.Map; import org.springframework.stereotype. ...
- [BZOJ 1412][ZJOI 2009] 狼和羊的故事
题目大意 有一个 (n times m) 的网格,每一个格子上是羊.狼.空地中的一种,羊和狼可以走上空地.现要在格子边上建立围栏,求把狼羊分离的最少围栏数. (1 leqslant n, ; m le ...
- JavaScript 設計模型 - Iterator
Iterator Pattern是一個很重要也很簡單的Pattern:迭代器!我們可以提供一個統一入口的迭代器,Client只需要知道有哪些方法,或是有哪些Concrete Iterator,並不需要 ...
- Python——9函数式编程②
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...