go语言的学习------数组与切片

数组

  • 数组是具有唯一类型的一组已编号且长度固定的数据项序列
  • 如果想让数组元素类型为任意类型的话,可以使用空接口作为类型
  • go语言中的数组是一种值类型(不像C/C++中是指向首元素的指针),所以可以通过new() 来创建 var arr=new([5]int)
数组定义的三种方式
  1. var arrAge = [5]int{18, 20, 15, 22, 16}
    [10]int{1,2,3}:这是一个有10个元素的,除了前三个其他元素都是0
  2. var arrLazy = […]int{5, 6, 7, 8, 22}
    …同样可以忽略,从技术上说它们其实变化成了切片
    切片和数组在声明时,最大的区别就是:数组需要长度(用…省略也是数组),而[]里面是空的则是切片
  3. var arrKeyValue = [5]string{3: “Chris”, 4: “Ron”}
    下标为3和4的被赋了值

将数组传递给函数会消耗很多内存,有俩中方法可以避免这种现象:

  1. 传递数组的指针
  2. 使用数组的切片

var arr1 = new([5]int)var arr1 [5]int的区别:
arr1的类型是*[5]int,而arr2的类型是[5]int

* 和 & 符号的讲解:
* 是一个指针变量 ,在一个类型前声明就是该类型的指针,在一个变量前声明就是取值
&是取址符 在变量前声明,会返回变量的地址
当一个指针被定义没有分配任何变量时,它的值是nil

切片
  • 切片是对数组一个连续片段的引用,所以切片是一个引用类型
  • 切片类似与C/C++中的数组类型,或者Python中的list类型
  • 和数组不同的是,切片的长度可以在运行时修改,最小为0最大为相关数组的长度
  • 切片是一个长度可变的数组

切片的初始化格式:var slice1 []type = arr1[start: end] (左闭有开)

切片在内存中的组织方式实际上是一个有3个域的结构体:指向相关数组的指针,切片长度以及切片容量
切片的长度就是从切片的首到切片的尾的长度
切片的容量就是从切片的首到数组的尾的长度cap()
一个切片s可以扩展到它的大小上限:s=s[:cap(s)]

切片可以被重新分片,但是只能获取到start后面的元素(包括end后面数组长度前面),但是不能获取到start前面的元素

用make()创建一个切片

当相关数组还没有定义时,我们可以使用make()函数来创建一个切片同时创建好相关数组:var slice1 []type = make([]type,len)
如:slice1 := make([]int,10),那么cap(s2)==len(s2)==10
slice1:=make([]T,len,cap)(cap是可选参数)

new()和make()的区别
  • func new(Type) *Type

  • func make(Type, size IntegerType) Type

  • new(T)为每个新的类型T分配一片内存,初始化为0并且返回类型为*T的内存地址;这种方式返回一个指向类型为T,值为0的地址的指针,它适用于值类型如数组和结构体;它相当于&T{}

  • make(T)返回一个类型为T的初始值,它只适用于3中内建的引用类型:切片,map和channel

  • 不特殊声明,go默认按值传递,即传递的参数的值的副本,但是make()返回的值通过传参可以进行修改

  • 很少使用new 在这里插入图片描述

多维切片
  • 通过分片的分片,长度可以任意动态改变,go语言中多维切片可以任意切分
  • 内层的切片必须单独分配(通过make函数)
bytes包 这个之后再看
For-range 结构
  • 第一个返回值是 数组或者切片的索引 (可以用来改变值)
  • 第二个返回值 是索引位置的值的一个拷贝,不能用来改变该索引位置的值
for ix, value := range slice1 {
    ...
}
// 只需要索引,可以忽略第二个值
for ix := range seasons {
    fmt.Printf("%d", ix)
}
// Output: 0 1 2 3
切片重组
  • slice1 = slice1[0:end],其中end是新的末尾索引(即长度)
 s1 = s1[0:len(s1)+1]
切片的复制和追加(没啥东西就没看)
切片

你将切片传递给函数时,实际上传递的是一个包含指向底层数组的指针、长度和容量的结构体的副本。这意味着如果你在函数中修改切片的元素,这些修改会反映在原始切片上。然而,如果你修改切片本身(例如,通过 append 增加元素),这些修改不会反映在原始切片上,因为你修改的是副本,而不是原始切片。

为了更清楚地说明这一点,让我们看看两种情况:

  • 直接修改切片的元素
package main

import "fmt"

func modifyElements(nums []int) {
    for i := range nums {
        nums[i] += 1
    }
}

func main() {
    nums := []int{1, 2, 3}
    modifyElements(nums)
    fmt.Println(nums) // [2, 3, 4]
}
  • 修改切片本身
package main

import "fmt"

func modifySlice(nums []int) {
    nums = append(nums, 4)
    fmt.Println("Inside function:", nums) // [1, 2, 3, 4]
}

func main() {
    nums := []int{1, 2, 3}
    modifySlice(nums)
    fmt.Println("Outside function:", nums) // [1, 2, 3]
}
  • 使用切片的指针修改可以起到在其它函数中添加元素的效果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值