Go语言学习
  • README
  • Go 基础
    • go语言介绍
    • go语言主要特性
    • go内置类型和函数
    • init函数和main函数
    • 下划线
    • iota
    • 字符串
    • 数据类型:数组与切片
    • 数据类型:byte、rune与字符串
    • 变量的5种创建方式
    • 数据类型:字典
    • 指针
    • 数据类型:指针
    • 类型断言
    • 流程控制:defer延迟执行
    • 异常机制:panic和recover
    • 函数
    • go依赖管理
    • go中值传递、引用传递、指针传递区别
  • 标准库
    • Go net/http包
  • 数据结构
    • 哈希表
      • 为什么对 map 的 key 或 value 进行取址操作是不允许的
  • Gin
    • gin 快速开始
    • gin-swagger用法
  • Go 进阶
    • Go 指针
    • Go 中的 GC 演变是怎样的?
    • Go 的堆和栈
  • 面向对象
    • make 和 new 的区别
    • new(T) 和 &T{} 有什么区别?
  • 并发编程
    • Channel
    • Go语言 CSP 并发模型
    • GMP 模型原理
      • GMP 模型为什么要有 P ?
    • Go 协程池(goroutine pool)
    • Go语言常见的并发模式
    • Go并发实践:主动停止goroutine
  • 最佳实践
    • 发布Go语言模块
  • 软件包
    • 常用的GoLang包工具
    • Go的UUID生成
    • 现代化的命令行框架Cobra
    • 配置解析神器Viper
    • Go发送邮件gomail
    • Go反射框架Fx
    • NSQ消息队列的使用
    • Go爬虫框架colly
    • grpc-go 的安装和使用
Powered by GitBook
On this page
  • GO数组特点
  • 数组定义
  • 切片
  • 切片初始化
  • slice 赋值和使用

Was this helpful?

  1. Go 基础

数据类型:数组与切片

GO数组特点

  • Go中的数组是值类型

  • 将一个数组赋值给另外一个数组,那么,实际上就是将整个数组拷贝一份

  • 如果Go中的数组作为函数的参数,那么实际传递的参数是一份数组的拷贝,而不是数组的指针。 因此,在Go中如果将数组作为函数的参数传递的话,那效率就肯定没有传递指针高了

  • array的长度也是Type的一部分 [3]int 和 [4]int Type是不一样的,如下代码:

import (
    "fmt"
)

func main() {
    arr01 := [...]int{1, 2, 3}
    arr02 := [...]int{1, 2, 3, 4}
    fmt.Printf("%d 的类型是: %T\n", arr01, arr01)
    fmt.Printf("%d 的类型是: %T", arr02, arr02)
}

输出 如下

[1 2 3] 的类型是: [3]int
[1 2 3 4] 的类型是: [4]int

数组定义

声明数组再赋值

// [3] 里的3 表示该数组的元素个数及容量
var arr [3]int
arr[0] = 1
arr[1] = 2
arr[2] = 3

声明并直接初始化数组 初始化数组的初始化有多种形式,示例代码如下:

arr := [5] int {1,2,3,4,5} 长度为5的数组,其元素值依次为:1,2,3,4,5

arr := [5] int {1,2} 长度为5的数组,其元素值依次为:1,2,0,0,0 在初始化时没有指定初值的元素将会赋值为其元素类型int的默认值0,string的默认值是""

arr := [...] int {1,2,3,4,5} 长度为5的数组,其长度是根据初始化时指定的元素个数决定的

arr := [5] int { 2:1,3:2,4:3} 长度为5的数组,key:value,其元素值依次为:0,0,1,2,3。 在初始化时指定了2,3,4索引中对应的值:1,2,3

arr := [...] int {2:1,4:3} 长度为5的数组,起元素值依次为:0,0,1,0,3 由于指定了最大索引4对应的值3,根据初始化的元素个数确定其长度为5赋值与使用

定义数组别名类型

每次写[3]int有点麻烦,你可以为[3]int定义一个类型字面量,也就是别名类型

使用type关键字可以定义一个类型字面量,后面只要你想定义一个容器大小为3,元素类型为int的数组 ,都可以使用这个别名类型。代码如下:

import (
    "fmt"
)

func main() {
    type arr3 [3]int

    myarr := arr3{1,2,3}
    fmt.Printf("%d 的类型是: %T", myarr, myarr)
}

输出 如下

[1 2 3] 的类型是: main.arr3

切片

数组的长度不可改变,在特定场景中这样的集合就不太适用

Go中提供了一种灵活,功能强悍的内置类型Slices切片(“动态数组"),* 与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大

切片中有两个概念:一是len长度,二是cap容量,长度是指已经被赋过值的最大下标+1,可通过内置函数len()获得。容量是指切片目前可容纳的最多元素个数,可通过内置函数cap()获得

切片是引用类型,因此在当传递切片时将引用同一指针,修改值将会影响其他的对象

切片初始化

切片可以通过数组来初始化,也可以通过内置函数make()初始化 . 初始化时len=cap,在追加元素时如果容量cap不足时将按len的2倍扩容

  • s :=[] int {1,2,3 } 直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3

  • s := arr[:] 初始化切片s,是数组arr的引用

  • s := arr[startIndex:endIndex] 将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片

  • s := arr[startIndex:] 缺省endIndex时将表示一直到arr的最后一个元素

  • s := arr[:endIndex] 缺省startIndex时将表示从arr的第一个元素开始

  • s1 := s[startIndex:endIndex] 通过切片s初始化切片s1

  • s :=make([]int,len,cap) 通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片

slice可以从一个数组或一个已经存在的slice中再次声明。slice通过array[i:j]来获取,其中i是数组的开始位置,j是结束位置,但不包含array[j],它的长度是j-i。

由于 切片是引用类型,不对它进行赋值的话,它的零值(默认值)是 nil

注意slice和数组在声明时的区别:

声明数组时,方括号内写明了数组的长度或使用...自动计算长度,而声明slice时,方括号内没有任何字符。

slice 赋值和使用

  • 切片可以通过内置函数append(slice []Type,elems ...Type)追加元素

  • elems可以是一排type类型的数据,也可以是slice,因为追加的一个一个的元素

  • 如果将一个slice追加到另一个slice中需要带上"...",这样才能表示是将slice中的元素依次追加到另一个slice中

  • 另外在通过下标访问元素时下标不能超过len大小,如同数组的下标不能超出len范围一样。

s := []int{3,2,1}
//一个元素的追加
s =append(s,1,2,3,4)
//将slice中的元素依次追加到另一个slice中
s1 := []int{10,20}
s =append(s,s1...)

import (
   "fmt"
)

func main() {
   myarr := []int{1} // [1]
   // 追加一个元素
   myarr = append(myarr, 2)//[1 2]
   // 追加多个元素
   myarr = append(myarr, 3, 4)//[1 2 3 4]
   // 追加一个切片, ... 表示解包,不能省略
   myarr = append(myarr, []int{7, 8}...)//[1 2 3 4 7 8]
   // 在第一个位置插入元素
   myarr = append([]int{0}, myarr...)//[0 1 2 3 4 7 8]
   // 在中间插入一个切片(两个元素)
   myarr = append(myarr[:5], append([]int{5,6}, myarr[5:]...)...) // [0 1 2 3 4 5 6 7 8]
   fmt.Println(myarr)
}
Previous字符串Next数据类型:byte、rune与字符串

Last updated 2 years ago

Was this helpful?