go语言基础(一):数组、字符串、切片

go语言基础(一):数组、字符串、切片

今天学习go语言里面的数组、字符串和切片。
在go语言中,数组、字符串和切片有着相似的数据结构,是三种联系紧密的数据类型。

数组

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。数组的长度是数组类型的组成部分。因为数组的长度是数组类型的一个部分,不同长度或不同类型的数据组成的数组都是不同的类型。

在go语言中,我们可以通过一下方式创建数组:

var a [3]int                    // 定义长度为3的int型数组, 元素全部为0
var b = [...]int{1, 2, 3}       // 定义长度为3的int型数组, 元素为 1, 2, 3
var c = [...]int{2: 3, 1: 2}    // 定义长度为3的int型数组, 元素为 0, 2, 3
var d = [...]int{1, 2, 4: 5, 6} // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6

在go语言中数组是一种值类型,在进行数组赋值和参数传递的时候是整体的值复制,如果数组较大的话,有可能影响程序的运行性能。一个数组变量即表示整个数组,不是表示指向数组第一个元素的指针。

为了避免数组的复制产生较大的性能开销,我们可以传递数组的指针,但数组的指针并不是数组。

array := [3]int {1,2,3} // 创建一个元素为1,2,3的整型数组
b := &array				// 将array的地址赋值给变量b,b为指向array数组的指针

fmt.Println(b[0])		// 1
fmt.Println(b[1])		// 2
fmt.Println(b[2])		// 3
数组访问

数组中的元素可以通过下标的方式,如array[index]。除此之外,go语言还可以通过for range的方式遍历数组。

for index, value := range array {
	fmt.Println(index, value)
}
修改元素

通过array[index] = value 的方式,可以向数组中添加元素或者修改元素。

获取数组长度

通过len(array) 方法可以获取当前数组的长度,cap(array)可以获取数组最大长度,对于数组类型来说,len和cap函数返回的结果始终是一样的,都是对应数组类型的长度。

切片(slice)

由于数组不够灵活,我们在实际中使用的比较少,go中又引入了切片,也就是动态数组。
在go语言中,切片的结构定义为:

// reflect.SliceHeader
type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

包含一个指向底层数组的变量、表示切片长度的变量和表示切片容量的变量。

切片的定义方式:

var (
    a []int               // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
    b = []int{}           // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
    c = []int{1, 2, 3}    // 有3个元素的切片, len和cap都为3
    d = c[:2]             // 有2个元素的切片, len为2, cap为3
    e = c[0:2:cap(c)]     // 有2个元素的切片, len为2, cap为3
    f = c[:0]             // 有0个元素的切片, len为0, cap为3
    g = make([]int, 3)    // 有3个元素的切片, len和cap都为3
    h = make([]int, 2, 3) // 有2个元素的切片, len为2, cap为3
    i = make([]int, 0, 3) // 有0个元素的切片, len为0, cap为3
)

同数组一样,切片能够使用len()、cap()方法获取切片的长度和容量。
与数组不同的是,切片中的长度和容量是可以不相等的,当切片已满时,长度等于容量,当切片未满时,长度小于容量,此时可以通过append()方法,向切片中添加元素:

  1. 向切片末尾追加元素:
var a []int
a = append(a, 1)               // 追加1个元素
a = append(a, 1, 2, 3)         // 追加多个元素, 手写解包方式
a = append(a, []int{1,2,3}...) // 追加一个切片, 切片需要解包
  1. 向切片开头添加元素:
var a = []int{1,2,3}
a = append([]int{0}, a...)        // 在开头添加1个元素
a = append([]int{-3,-2,-1}, a...) // 在开头添加1个切片
  1. 向切片中间添加元素:
var a []int
a = append(a[:i], append([]int{x}, a[i:]...)...)     // 在第i个位置插入x
a = append(a[:i], append([]int{1,2,3}, a[i:]...)...) // 在第i个位置插入切片

在切片中删除元素,可以通过以下方式实现:

  1. 删除尾部元素:
a = []int{1, 2, 3}
a = a[:len(a)-1]   // 删除尾部1个元素
a = a[:len(a)-N]   // 删除尾部N个元素
  1. 删除头部元素:
a = []int{1, 2, 3}
a = a[1:] // 删除开头1个元素
a = a[N:] // 删除开头N个元素

删除开头的元素也可以不移动数据指针,但是将后面的数据向开头移动。可以用append原地完成(所谓原地完成是指在原有的切片数据对应的内存区间内完成,不会导致内存空间结构的变化):

a = []int{1, 2, 3}
a = append(a[:0], a[1:]...) // 删除开头1个元素
a = append(a[:0], a[N:]...) // 删除开头N个元素

也可以用copy完成删除开头的元素:

a = []int{1, 2, 3}
a = a[:copy(a, a[1:])] // 删除开头1个元素
a = a[:copy(a, a[N:])] // 删除开头N个元素
  1. 删除中间元素:
a = []int{1, 2, 3, ...}

a = append(a[:i], a[i+1:]...) // 删除中间1个元素
a = append(a[:i], a[i+N:]...) // 删除中间N个元素

a = a[:i+copy(a[i:], a[i+1:])]  // 删除中间1个元素
a = a[:i+copy(a[i:], a[i+N:])]  // 删除中间N个元素

切片的遍历和数组类似:

for i := range a {
    fmt.Printf("a[%d]: %d\n", i, a[i])
}
for i, v := range b {
    fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(c); i++ {
    fmt.Printf("c[%d]: %d\n", i, c[i])
}

字符串

一个字符串是一个不可改变的字节序列,与数组不同的是,字符串的元素不可修改,是一个只读数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值