main.go
// Go语言数组和切片
package main
// 包的本质是创建不同的文件夹
// go的每一个文件都是属于一个包的
// go以包的形式管理项目和文件目录。
// import "包的路径"
import (
"day7/model/utils"
_"fmt"
)
var content string = `
————————————————Go语言数组和切片————————————————————
一、数组
二、切片
`
/**
* [init init函数初始化工作。main函数之前执行]
* @author Jhou Shuai
* @datetime 2019-05-20T22:49:36+0800
*/
// func init() {
// fmt.Println(content)
// }
func main() {
utils.Entry()
}
utils.go
// Go语言数组和切片
package utils
import (
"fmt"
"strings"
)
var layout string = "2006-01-02"
// 全局变量
var Author string = "Jhou Shuai"
// 全局变量
var Description string = "Go语言数组和切片"
//全局变量:使用反引号来定义多行字符串
var Content string = `
————————————————Go语言数组和切片————————————————————
一、数组
1)数组是值类型:
2)数组可以存放多个同一类型的数据
3)增加程序可维护性
4)代码更加清晰,易扩展
二、切片
1.切片的长度是可以变化的,是一个动态变化数组
切片的容量是可以动态变化的
var 切片名 []类型
var intSlice []int
第一种: mySlice := intArr[1:3]
2.切片在内存中的表现形式
3.切片引用类型:在传递时候,遵守引用传递机制
4.数据结构:struct结构体
type slicestuct{
ptr *[2]int
len int
cap int
}
5.第二种:make 创建切片
类型,长度,容量
cap>=len
var 切片名 []type = make([]type,len,[cap])
var slice []float64 = make([]float64, 5,10)
6.第三种:定义一个切片,直接就指定具体的数组
var strSlice []string = []string{"Faker","Uzi","Mata"}
`
/**
* [Init 入口]
* @author Jhou Shuai
* @datetime 2019-05-18T11:58:33+0800
*/
func Entry() {
[1 1 2 3 5 8 13 21 34 55]
fmt.Println(fbn(10))
}
func sliceInit() {
// 第一种方式:
// var intArr [5]int = [...]int{1,22,33,44,55}
// // 切片操作:
// // 1.
// // 引用intArr数组的起始下标为1,最后的下标为3(不包含3)
// mySlice := intArr[1:3]
// fmt.Println("intArr= ",intArr)
// fmt.Println("mySlice中的元素:",mySlice)
// fmt.Println("mySlice中的长度:",len(mySlice))
// // 切片的容量是可以动态变化的
// fmt.Println("mySlice中的容量:",cap(mySlice))
// fmt.Println()
// // 数组的各个元素的地址间隔是依据数组的类型决定的,
// // 比如:int64->8个字节、int32->4个字节 int16 ->2个字节 、int->8个字节
// fmt.Printf("intArr地址%p \n",&intArr)
// for i := 0; i <len(intArr); i++ {
// fmt.Printf("intArr[%v]的地址%p \n",i,&intArr[i])
// }
// fmt.Println()
// fmt.Printf("mySlice地址%p \n",&mySlice)
// for i := 0; i <len(mySlice); i++ {
// fmt.Printf("mySlice[%v]的地址%p \n",i,&mySlice[i])
// }
// mySlice[1] = 66
// fmt.Println("intArr= ",intArr)
// fmt.Println("mySlice中的元素:",mySlice)
// 第二种方式:
fmt.Println()
var slice []float64 = make([]float64, 5,10)
// 对于切片必须,make才能使用
// [0 0 0 0 0] 默认全部为零
slice[1] = 64
slice[3] = 100
fmt.Printf("元素:%v,长度:%v,容量:%v \n",slice,len(slice),cap(slice))
for i := 0; i <len(slice); i++ {
fmt.Printf("slice[%v]的地址%p \n",i,&slice[i])
}
// 元素:[0 64 0 100 0],长度:5,容量:10
// slice[0]的地址0xc0000700f0
// slice[1]的地址0xc0000700f8 0xc0000700f8 = 0xc0000700f0 + 8
// slice[2]的地址0xc000070100 0xc000070100 = 0xc0000700f8 + 8
// slice[3]的地址0xc000070108 0xc000070108 = 0xc000070100 + 8
// slice[4]的地址0xc000070110 0xc000070110 = 0xc000070108 + 8
// 通过make方式创建切片可以指定切片的大小和容量
// 如果没有给切片的各个元素赋值,那么就会使用默认值
// int float => 0
// string => ""
// bool => false
// 通过make方式创建的切片对应的数组是由make底层维护,对外
// 不可见,即只能通过slice去访问各个元素。
//
// 第三种方式:
fmt.Println()
var strSlice []string = []string{"Faker","Uzi","Mata"}
fmt.Printf("元素:%v,长度:%v,容量:%v \n",strSlice,len(strSlice),cap(strSlice))
for i := 0; i <len(strSlice); i++ {
fmt.Printf("strSlice[%v]的地址%p \n",i,&strSlice[i])
}
// 元素:[Faker Uzi Mata],长度:3,容量:3
// strSlice[0]的地址0xc000080300
// strSlice[1]的地址0xc000080310 0xc000080310 = 0xc000080300 + 16
// strSlice[2]的地址0xc000080320 0xc000080320 = 0xc000080310 + 16
//
//
// 第一种方式和第二种方式的区别:
// 第一种方式:
// 直接引用数组,这个数组是事先存在的,是可见的
// 第二种方式:
// 通过make来创建切片,make也会创建一个数组,是由切片在
// 底层维护,是不可见的
}
func sliceForRange() {
var intArr [5]int = [...]int{10,20,30,40,50}
intSlice := intArr[0:]
for i := 0; i <len(intSlice); i++ {
fmt.Printf("intSlice[%v] = %v \n",i,intSlice[i])
}
fmt.Println()
for key,value := range intSlice {
fmt.Printf("intSlice[%v] = %v \n",key,value)
}
fmt.Println()
for _,value := range intSlice {
fmt.Printf( "%v \t",value)
}
}
/**
* [sliceUseDetail 切片注意事项和细节说明]
* @author Jhou Shuai
* @datetime 2019-05-29T20:41:33+0800
*/
func sliceUseDetail() {
// 不要越界
// var slice = arr[startIndex,endIndex]
// 从arr数组下标startIndex,取到下标为endIndex的元素(不含arr[endIndex])
// var slice = arr[:len(arr)]
// var slice = arr[start:]
// var slice = arr[:end]
// var slice = arr[:]
//
// cap 容量
// 可以多次切片,切了在切,
//
// append 内置函数
// 可以对切片进行动态追加
var intSlice []int = []int{100,200,300}
fmt.Println(intSlice)
for i := 0; i <len(intSlice); i++ {
fmt.Printf("intSlice[%v]的地址%p \n",i,&intSlice[i])
}
// 通过append直接给intSlice追加元素
intSlice0 := append(intSlice,400,500)
fmt.Println(intSlice0)
for i := 0; i <len(intSlice0); i++ {
fmt.Printf("intSlice0[%v]的地址%p \n",i,&intSlice0[i])
}
// 通过append将切片intSlice追加给intSlice
intSlice = append(intSlice,intSlice...)
fmt.Println(intSlice)
// 切片append操作的本质是对数组扩容
// 不是针对原来的数组,而是
// go底层会创建一个新的数组newArr(按照扩容后大小)
// 刚创建所有默认值为零;然后
// 将intSlice原来包含的元素拷贝到新的数组newArr
// 切片intSlice重新应用新数组newArr
// 新的数组newArr是在底层维护,不可见的
// 原来的数组就会被回收。
// 切片的拷贝 copy 两个参数的数据类型:切片
// 两个切片的数据空间是独立。相互不影响
// 切片类型才可以执行copy
fmt.Println()
var slice4 []int = []int{1,2,3,4,5};
var slice5 = make([]int, 10)
copy(slice5,slice4)
fmt.Println(slice4)
for i := 0; i <len(slice4); i++ {
fmt.Printf("slice4[%v]的地址%p \n",i,&slice4[i])
}
// [1 2 3 4 5]
// slice4[0]的地址0xc000094090
// slice4[1]的地址0xc000094098
// slice4[2]的地址0xc0000940a0
// slice4[3]的地址0xc0000940a8
// slice4[4]的地址0xc0000940b0
fmt.Println(slice5)
for i := 0; i <len(slice5); i++ {
fmt.Printf("slice5[%v]的地址%p \n",i,&slice5[i])
}
// [1 2 3 4 5 0 0 0 0 0]
// slice5[0]的地址0xc0000700f0
// slice5[1]的地址0xc0000700f8
// slice5[2]的地址0xc000070100
// slice5[3]的地址0xc000070108
// slice5[4]的地址0xc000070110
// slice5[5]的地址0xc000070118
// slice5[6]的地址0xc000070120
// slice5[7]的地址0xc000070128
// slice5[8]的地址0xc000070130
// slice5[9]的地址0xc000070138
// slice5,slice4是两个相互独立的空间
//
// 不会报错,只会拷贝一个
var slice6 = make([]int, 1)
copy(slice6,slice4)
// [1]
fmt.Println(slice6)
}
/**
* [stringSlice 字符串、切片]
* @author Jhou Shuai
* @datetime 2019-05-29T22:15:32+0800
*/
func stringSlice() {
// string底层是一个byte数组,因此也可以进行切片处理
// string和切片在内存的形式:
var name string = "ZhouShuai@163.com"
var strSlice =name[strings.Index(name,"@"):]
fmt.Println(strSlice)
// string是不可变的,也就是不能通过str[0]='z'方式来修改字符串
//
//
// 如果需要修改字符串,可以将string-》[]byte 或[]rune->修改-》重写转成string
arrSlice := []byte(name)
arrSlice[0]='J'
var arrStr = string(arrSlice)
// JhouShuai@163.com
fmt.Println(arrStr)
// []byte
// 转成[]byte后,可以处理英文和数字,不能处理中文
// 原因是[]byte字节来处理,而一个汉字,是三个字节,因此会出现乱码
//
// []rune
// 解决方法是:将string 转成[]rune 即可,因为[]rune是按字符处理的
// 可以兼容汉字
arrSlice1 := []rune(name)
arrSlice1[0]='周'
var arrStr1 = string(arrSlice1)
// 周houShuai@163.com
fmt.Println(arrStr1)
}
/**
* [fbn 斐波拉契数列]
* @author Jhou Shuai
* @datetime 2019-05-29T22:59:40+0800
* [1 1 2 3 5 8 13 21 34 55]
* fmt.Println(fbn(10))
*/
func fbn(n int) ([]uint64) {
/**
* 思路:
* 1.声明一个函数,fbn(n int) ([]uint64){}
*/
var fbnSlice = make([]uint64, n)
fbnSlice[0] = 1
fbnSlice[1] = 1
for i := 2; i <n; i++ {
fbnSlice[i] = fbnSlice[i-1] + fbnSlice[i-2]
}
return fbnSlice
}
网友评论