栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

golang学习笔记008--数组,切片和二维数组

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang学习笔记008--数组,切片和二维数组

目录
  • 1.数组
    • 1.1数组介绍
    • 1.2数组的使用
    • 1.3数组的遍历
    • 1.4数组使用注意事项
    • 1.5 随机生成5个数,并反转
  • 2.切片slice
    • 2.1基本介绍
    • 2.2 切片的使用
      • 方式一:引用数组
      • 方式二:make
      • 方式三:
      • 方式一和方式二的区别:
    • 2.3 切片的遍历
    • 2.4 使用注意事项
  • 3.string和slice
  • 4.二维数组
    • 4.1 入门
    • 4.2 使用方式1:先声明,在赋值
    • 4.3 使用方式2:直接初始化
    • 4.4 二维数组遍历

1.数组 1.1数组介绍
  • 数组可以存放多个同意类型的数据,数组也是一种数据类型,在go中,数组是值类型
  • 定义: var 数组名[数组大小] 数据类型
  • var a [5] int
  • 赋初值 a[0]=1 a[1]=2
  • 数组的地址可以通过数组名来获取&intArr
  • 数组的第一个元素的地址,就是数组的首地址
  • 数组的各个元素的地址间隔是依据数组的类型决定,比如int64->8 int32->4

1.2数组的使用

● 访问数组元素:数组名[下标] 比如:你要使用a数组的第三个元素 a[2]

● 四种初始化数组的方法

1.3数组的遍历

(1) 常规遍历
(2) for-range遍历
for index,values:= range array{
…
}
说明:
○ 第一个返回值index是数组的下标
○ 第二个返回值value是该下表位置的值
○ 他们都是仅在for循环内部可用的局部变量
○ 遍历时,如果不想使用下表用_代替忽略
○ index,value名称不是固定的,一般为index和value

package main

import (
	"fmt"
)

func main(){
	arr := [3]int{10,20,30}
	for index,value :=range arr{
		fmt.Println(index,value)
	}
}
1.4数组使用注意事项
● 数组是多个相同类型数据的集合,一个数组一旦声明,其长度是固定的,不能动态变换
● var arr[] int 这是arr就是一个slice切片
● 数组创建后,若没有赋值,有默认值(零值)
  ○ 数值类型:0
  ○ 字符串:""
  ○ bool:false
● 使用数组的步骤:
  ○ 声明数组并开辟空间
  ○ 给数组个元素赋值
  ○ 使用数组
● 数组下标从0开始

● go语言数组属于数值型,在默认情况下是值传递,因此会进行值拷贝,数组间不会相互影响

● 如果在其他函数中,去修改原来的数组,可以使用引用传递(指针方式)

● 长度是数组类型的一部分,在传递函数参数时,需要考虑数组长度

1.5 随机生成5个数,并反转

2.切片slice 2.1基本介绍

● 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制
● 切片和数组类似,遍历切片,访问切片的元素和求切片长度len(slice)都一样
● 切片的长度是可变的,因此切片是一个可以动态变换的数组
● 切片定义的基本语法: var 切片名 [] 类型 比如:var a[] int

package main

import (
	"fmt"
)

func main(){
	intArr := [5]int{1,22,33,66,99}

	slice :=intArr[1:3]//定义一个切片,slice就是切片名称
					//arr[1,3]表示slice引用intArr这个数组,引用arr数组起始下标为1至下标为3(不包含3)

	fmt.Println("intArr=:" ,intArr)//intArr=: [1 22 33 66 99]
	fmt.Println("slice 的内容" , slice)//slice 的内容 [22 33]
	fmt.Println("slice 长度为" , len(slice))//slice 长度为 2
	fmt.Println("slice 的容量为" ,cap(slice))//	slice 的容量为 4
	
}

● 内存结构:

● 对上图说明:
  ○ slice是一个引用类型
  ○ slice从底层来说是一个数据结构(struct结构体)
	type slice struct{
		ptr *[2]int
		len int
		cap int
	}
2.2 切片的使用 方式一:引用数组

定义一个切片,然后去引用一个已经创建好的数组,比如上面的方式

方式二:make

通过make来创建切片
基本语法:var 切片名 [] type = make([]type,len,[cap])
参数说明:type:数据类型 len:大小 cap:指定切片容量,可选,如果分配cap,则cap>=len

package main

import (
	"fmt"
)

func main(){
	var slice2 []float64 =make([]float64,5,10)
	slice2[0]=10
	slice2[3]=20
	fmt.Println("slice2 的内容" , slice2)//slice2 的内容 [10 0 0 20 0]
	fmt.Println("slice2 长度为" , len(slice2))//slice2 长度为 5
	fmt.Println("slice2 的容量为" ,cap(slice2))//slice2 的容量为 10
}

内存

小结:
● 通过make方式创建切片可以指定切片的大小和容量
● 如果没有给切片的个元素赋值,则为默认值
● 通过make方式创建的切片对应的数组是由make底层维护的,对外不可见,只能通过slice去访问各个元素

方式三:

定义一个切片,直接就指定具体数组,使用原理类似make方式

package main

import (
	"fmt"
)

func main(){
	var slice3 []string =[]string{"tom","jack","mary"}
	fmt.Println("slice3 的内容" , slice3)//slice3 的内容 [tom jack mary]
	fmt.Println("slice3 长度为" , len(slice3))//slice3 长度为 3
	fmt.Println("slice3 的容量为" ,cap(slice3))//slice3 的容量为 3
}
方式一和方式二的区别:

● 方式一是直接引用数组,这个数组是事先存在的,程序员可见的
● 方式二是通过make来创建切片,make也会创建一个一个数组,是由切片在底层维护,程序员不可见

2.3 切片的遍历

● for循环
● for-range

2.4 使用注意事项
  1. 切片初始化时 var slice =arr[startIndex:endIndex]
    ○ 说明:从arr数组下标为startInde取到endIndex的元素(不包含endIndex)
    ○ var slice =arr[0:end]可以简写 var slice=arr[:end]
    ○ var slice =arr[start:len(arr)]可以简写 var slice=arr[start:]
    ○ var slice =arr[0:len(arr)]可以简写 var slice=arr[:]

  2. 切片初始化时,仍然不能越界,但是可以动态增长

  3. cap是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素

  4. 切片定义完后,还不能使用,因为本身一个空的,需要让其引用到一个数组,或者make一个空间供切片来使用

  5. 切片可以继续切片

package main

import (
	"fmt"
)

func main(){

	var slice2 []float64 =make([]float64,5,10)
	slice2[0]=10
	slice2[3]=20

	slice4 := slice2[0:2]
	fmt.Println("slice4 的内容" , slice4)//slice4 的内容 [10 0]
	fmt.Println("slice4 长度为" , len(slice4))//slice4 长度为 2
	fmt.Println("slice4 的容量为" ,cap(slice4))//slice4 的容量为 10
}
  1. 用append内置函数,可以对切片进行动态追加
	ar slice5 []int=[]int{100,200,300}
	//追加具体元素
	slice5 = append(slice5,400,500,600)
	fmt.Println("slice5=",slice5)//slice5= [100 200 300 400 500 600]
	
	//追加切片
	slice5=append(slice5,slice5...)
	fmt.Println("slice5=",slice5)//slice5= [100 200 300 400 500 600 100 200 300 400 500 600]

○ 切片append操作的本质就是对数组扩容
○ go底层会创建一个新的数组newArr
○ 将slice原来包含的元素拷贝到新的数组newArr中
○ slice重新引用到newArr
○ 注意newArr是在底层来维护的,程序员不可见

  1. 切片的拷贝操作
    ○ 切片使用copy内置函数完成拷贝
    ○ copy(slice6,slice5)参数的数据类型都是切片
    ○ slice6,slice5的数据空间都是独立的,相互不影响
	var slice5 []int=[]int{100,200,300}
	slice5 = append(slice5,400,500,600)
	fmt.Println("slice5=",slice5)//slice5= [100 200 300 400 500 600]
	
	var slice6 =make([]int,10)
	copy(slice6,slice5)
	fmt.Println("slice6=",slice6)//slice6= [100 200 300 400 500 600 0 0 0 0]
  1. 这段代码没问题,可以运行,输出[1],空间不够不报错
  2. 切片是引用类型,引用传递
3.string和slice

● string底层是一个byte数组,因此string也可以进行切片处理

	str := "wang"
	slice:= str[0:2]
	fmt.Println(slice)//wa

● string和切片内存形式

● string是不可变的,不能通过str[0]="a"来修改字符串
● 如果需要修改,可以先将stirng转为[]byte 或[]rune修改完转换为string

	str := "wang"
	slice:= str[0:2]
	fmt.Println(slice)//wa
	arr1 := []byte(str)
	arr1[0] = 'a'
	str=string(arr1)
	fmt.Println(str)//aang

如果包含汉字,转为[]rune

	str := "wang"
	slice:= str[0:2]
	fmt.Println(slice)//wa
	arr1 := []rune(str)
	arr1[0] = '王'
	str=string(arr1)
	fmt.Println(str)//王ang
4.二维数组 4.1 入门
var arr [2][3]int
	arr[0][2]=1
	arr[1][1]=2

	for i:=0;i<2;i++{
		for j:=0;j<3;j++{
			fmt.Print(arr[i][j]," ")
		}
		fmt.Println()
	}
	//0 0 1
	//0 2 0
4.2 使用方式1:先声明,在赋值

● 语法: var 数组名 [大小][大小] 类型
● 比如 var arr[2][3]int
● 二维数组内存结构

4.3 使用方式2:直接初始化
● var arr [2][3]int = [2][3]int {{1,2,3},{4,5,6}}
● 写法
  ○ var 数组名 [大小][大小]类型 = [大小][大小] 类型{{值},{值}}
  ○ var 数组名 [大小][大小]类型 = [...][大小] 类型{{值},{值}}
  ○ var 数组名= [大小][大小] 类型{{值},{值}}
  ○ var 数组名 = [...][大小] 类型{{值},{值}}
4.4 二维数组遍历

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/965748.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号