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的方式的更多相关文章

  1. Java学习笔记-多线程-创建线程的方式

    创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...

  2. Wireshark工具创建过滤器的方式

    Wireshark工具创建过滤器的方式  [实例1-3]现在要抓取目的或来源地址为192.168.5.9的封包.在图1.5中添加如下所示的条件: tcp dst port 3128 添加后单击Star ...

  3. Java多线程学习总结--线程概述及创建线程的方式(1)

    在Java开发中,多线程是很常用的,用得好的话,可以提高程序的性能. 首先先来看一下线程和进程的区别: 1,一个应用程序就是一个进程,一个进程中有一个或多个线程.一个进程至少要有一个主线程.线程可以看 ...

  4. JS面向对象编程创建类的方式

    js创建类的方式有几种,大致如下: 1,构造函数方式: function Car(parameters) { this.name = "objectboy"; } var cat1 ...

  5. java中创建多线程的方式

    在java中比较常用的有三种创建多线程的方式. 方式一:继承Thread类,要重写run方法. 在MyThread类 public class MyThread extends Thread { @O ...

  6. Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式

    Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...

  7. 7. Callable 创建线程的方式三

    package com.gf.demo06; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionEx ...

  8. Vue 创建组件的方式

    Vue 创建组件的方式 2018年08月07日 11:10:56 虔诚带着决然 阅读数:1015   版权声明:本文为博主原创文章,未经博主允许不得用做其他商业活动. https://blog.csd ...

  9. @Scope注解设置创建bean的方式和生命周期

    1.1.1            Scope注解创建bean的方式和生命周期 作用 Scope设置对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式. 取 ...

随机推荐

  1. RabbitMQ传输原理、五种模式

    本文代码基于SpringBoot,文末有代码连接 .首先是一些在Spring Boot的一些配置和概念,然后跟随代码看下五种模式 MQ两种消息传输方式,点对点(代码中的简单传递模式),发布/订阅(代码 ...

  2. unique()函数使用

    前提:要先令容器有序. unique的作用是“去掉”容器中相邻元素的重复元素(不一定要求数组有序),它会把重复的元素添加到容器末尾(所以数组大小并没有改变),而返回值是去重之后的尾地址. 用法:uni ...

  3. unittest(7)-作业- 全局变量传递cookie

    全局变量存储cookie 测试类中有多个测试函数 # 1.http_requset.py import requests class HttpRequest: def http_request(sel ...

  4. 吴裕雄--天生自然python编程:turtle模块绘图(2)

    #彩色螺旋线 import turtle import time turtle.pensize(2) turtle.bgcolor("black") colors = [" ...

  5. Word目录生成

    之所以写这篇文章,是因为每次写报告都需要生成相应目录,但常常只记得个大概,最终还得要重新百度,十分头疼,故在此记录一下. 大概分为3个步骤 步骤1 设置标题级数 进入大纲模式 选择相应级数,这里选的是 ...

  6. php发送post请求的4种方式

    http://blog.163.com/fan_xy_qingyuan/blog/static/188987748201411943815244/ class Request{ public stat ...

  7. 云服务器之——Linux下配置JDK环境

    在Linux下jdk的安装已经操作了很多次,每次发现自己还是会忘记之前的操作,所以今天就简单的来做个记录. 第一步:下载jdk安装包 登录oracle官网:https://www.oracle.com ...

  8. python有关汉字编码问题

    python分为:程序编码(python安装程序).文件编码. 查看程序编码方式:sys.getdefaultencoding() 查看文件编码方式:1.import  chardet  2. f = ...

  9. UMD: 通用模块规范

    既然CommonJs和AMD风格一样流行,似乎缺少一个统一的规范.所以人们产生了这样的需求,希望有支持两种风格的“通用”模式,于是通用模块规范(UMD)诞生了.

  10. /lib64/libc.so.6: version `GLIBC_2.18' not found报错解决

    今日安装一区块链服务时报错:/lib64/libc.so.6: version `GLIBC_2.18' not found,检查后现有的glibc版本是2.17,然后参考https://www.ji ...