go语言学习--基础篇(3)
一,go语言数组
1,数组的特点
a. 数组在初始化完成之后,数组的长度是固定的
b. 只存储同一类型的数据
c. 数组中的元素与元素之间的内存空间是连续的
2,数组的定义
var a [5]int 其中a 表示数组的名称,[5]表示数组的长度,int 表示数组中的元素类型
3,数组中元素的访问
使用下标访问 a[0],a[1],a[2]
4,循环获取数组每个元素的地址
package main import ( "fmt" ) func main() { var a [10]int for i :=0;i <10; i++{ fmt.Printf("%p\n", &a[i]} } } 输出结果: #明显每个元素占8个字节,而且是连续的 0xc04206e050 #int 类型所占的内存空间和操作系统有关 64位操作系统,int 占64位,即8个字节 0xc04206e058 0xc04206e060 0xc04206e068 0xc04206e070 0xc04206e078 0xc04206e080 0xc04206e088 0xc04206e090 0xc04206e098
5,数组长度
var a[10]int length := len(a)
6,数组存在越界问题
var a[10]int 长度为10,下标范围为0到9。访问0到9之外的小标会报错
7,数组的遍历
/* range 遍历数组 */ package main import ( "fmt" ) func main() { var a [10]int for index,val := range a{ fmt.Printf("a[%d] = %d\n",index,val) } }
8, 值类型
func test() { var a [5]int = [5]int {1,2,3,4,5} var b [5]int b = a fmt.Printf("b=%v\n",b) b[0] = 200 fmt.Printf("b=%v\n",b) fmt.Printf("a=%v\n",a) } #输出结果为 #b=[1 2 3 4 5] #b=[200 2 3 4 5] #a=[1 2 3 4 5] #从中可以看出改变数组b中的元素,并不会改变数组a中的元素,这就是值类型
9,数组的初始化
a. var a[5] int = [5]int {1,2,3,4,5}
b. var a = [5]int{1,2,3,4,5}
c. var a = [...]int{1,2,3,4,5} 其中[...]表示不确定长度
d. var a = [5]string{1:"abc",2"eft"} 表示给数组a的前两个元素赋值为a[0]=abc,a[1]=eft
10,二维数组定义
var a[8][2]int 定义一个8行2列的数组
二,切片
切片的长度是动态的,任何切片底层都为数组
1,切片的定义, 与数组的定义唯一的区别就是没有长度,并且默认长度为0
var 变量名 [ ] type
a. var a [] string
b. var a [] float32
2,切片的初始化(切片为引用类型)
var a [5] int
var b []int = a [0:2]
var b []int = a [2:]
var b []int = []int{1,2,3,4,5}
3,示例思考
可以看出a 的值改变,相应的切片b的值也会变,说明切片为指针类型或者引用类型
package main import( "fmt" ) func main(){ var a [5]int b :=a[1:3] a[0] =100 a[1] =200 fmt.Printf("b:%#v\n",b) }
输出为:
b:[]int{200,0}
4,切片的内存布局
x 为一个切片,切片的形式包含三个内容,指向底层数组的指针,定义切片的长度和切片的容量
5,传数组与传切片
package main import ( "fmt" ) func Sum(b []int){ b[0] = 100 } func SumArry(b [100]int){ b[0] = 100 } func main(){ var a [100]int a[0] = 1 a[1] = 2 a[2] = 3 Sum(a[:]) fmt.Printf("a:%d\n",a[0]) a[0] = 1 #重置a[0]的值 SumArry(a) fmt.Printf("a:%d\n",a[0]) } #输出为 #a:100 #a:1 #从输出结果可以看出 传入参数为切片时,底层数组的值可以被改变,当传入是数组时,数组的值不能改变,#再次说明切片为指针类型或者引用类型,而数组为数值类型
6,切片的创建
var b []int
b = make([]int,5,10)
a. 指定切片容量 make([]type,len,cap)
b. 不指定切片容量,容量就等于长度 make([]type,len),
注意:
以make 方式创建一个数组,其底层也一个数组,有make 创建
7,切片的内存操作copy 和 append 操作,append 会对切片进行扩容,增加内存
将一个切片append 到另一个切片
func testAppend(){ var a []int a = make([]int,5) var b[]int = []int{10,11,12,14} a =append(a,b...) #b... 展开切片b的所有元素 ftm.Printf("a:%#v\n",a) }
8,字符串的内存布局
在go 语言中,字符串也是一个切片,内存布局如下图
a,ptr 为指针
b,len为长度,
c,容量也就是长度
d,类型为byte
9,修改字符串中某个字符
func testStrSlice() { var str = 'hello world" var b []byte = []byte(str) #请字符串转化成切片 b[0] = 'a' #修改切片第一个值 str1 :=string(b) #将切片转化成string fmt.Printf("str1:%s\n",str1 }