一、数组
-连续存储的内存空间,因此不能添加元素,总不能内存往后挤吧
-长度和类型在定义阶段就固定了(...的使用:可以接受任意长度,但是定义时取决于后面传入几个值,也是固定长度,见下方)
-定义并初始化的时候,可以只指定某个位置的值-数组长度 len
-数组的大小也是类型的一部分,大小不一样类型就不一样
-数组是值类型,使用时时copy原数组,不会改变原数组,和python中不可变类型一样
-循环数组
-range
-多维数组
-var a [3][4]int
var a = [...]int {x,c,v, } // 不是变长数组,也不能说是不定长数组,定义时长度绝对是固定的只是依赖于后面传入几个值,这个数组大小就是3
//数组 在定义阶段,长度和类型就固定了,以后不能更改
package main
import "fmt"
func main() {
//var a [5]int //定义了一个长度为5的int类型数组
//a[1]=100 //把2号位置放上100
//fmt.Println(a)
//定义并赋初值
//var a [6]int=[6]int{1,2,3,4,5,6}
//var a =[6]int{1,2,3} //没传的是int的默认值0
//a :=[6]int{1,2,3}
//a[5]=100
//fmt.Println(a)
//先按位置传参,然后索引传参
//a :=[100]int{1,2,98:99,87:88}
////a[-9]=19 不支持负索引
//fmt.Println(a)
//数组是值类型,所有的函数传参都是copy传递(和python中不可变类型一样)
//a:=[4]int{1,2,3}
//test6(a)
//fmt.Println(a)
//数组的长度 内置函数len
//fmt.Println(len(a))
//数组大小是类型一部分
//var a [4]int=[4]int{1,2,}
//var b [5]int=[5]int{4,5,}
//a=b //飘红 报错,长度不一样不能转换
//fmt.Println(a,b)
//与或非
//&& || !
//a:=10
//if !(a>9||a<6){
//
//}
//数组迭代(遍历)
//var a [4]int=[4]int{1,2,}
//for i:=0;i<len(a);i++{
// fmt.Println(a[i])
//}
//通过range关键字迭代
//var a [4]int=[4]int{1,2,}
//for i,v:=range a { // 索引和值都要
////for i:=range a { // 只接受索引
// fmt.Println("------",i)
// fmt.Println(v)
//}
//多维数组
var a [7][2]int
a[0][1]=100
fmt.Println(a) //[[0 100] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]
}
func test6(b [4]int) {
b[0]=100
fmt.Println(b)
}
二、切片
1.第一种方式,由数组切出来
package main
import "fmt"
func main () {
//切片定义的第一种方式,由数组切出来
var a [8]int=[8]int{1,2,3,4,5,6,7,8} //定义数组
////是对数组的引用
////底层数组的修改会影响切片
////切片的修改也会影响底层数组
var b []int=a[2:6]
fmt.Println(b) //[3 4 5 6]
a[2]=30
fmt.Println(b) //[30 4 5 6]
b[1]=40
fmt.Println(b) //[30 40 5 6]
fmt.Println(a) //[1 2 30 40 5 6 7 8]
//更多用法,没有步长
f:=a[:4] //[1 2 30 40]
//f:=a[:] //[1 2 30 40 5 6 7 8]
fmt.Println(f)
}
2.第二种,直接定义
package main
import "fmt"
func main () {
//第二种方式,直接定义并初始化,第一个数字是切片的长度 len,第二个数字是底层数组总长度,也就是切片的容量cap
// 1.先拿一个切出来的切片示范,便于理解
// var a [8]int=[8]int{1,2,3,4,5,6,7,8}
// var b []int=a[2:6]
// fmt.Println(len(b)) //4
// fmt.Println(cap(b)) //6
//2.直接定义并初始化
var a []int=make([]int,3,4)
fmt.Println(a) //[0 0 0]
fmt.Println(len(a)) //3
fmt.Println(cap(a)) //4
//切片空值是 nil 类型,不能传值
//var a []int
//if a==nil{
// fmt.Println("我是空的")
//}
//a[0]=10
//fmt.Println(a) //这样就报错了 ,相当于你定义了一个none然后给none传值,不报错才怪呢
}
3.切片 追加值
package main
import "fmt"
func main () {
// 第一种切片:切来的
var a [8]int=[8]int{0,1,2,3,4,5,6,7}
var b []int=a[2:6]
fmt.Println(len(b),b) //4 [2 3 4 5 ]
fmt.Println(cap(b)) //6 切片容量 :切别人的,容量不是整个数组长度,而是从切的位置到数组末尾
//利用内置函数append 追加值
b=append(b,555)
b=append(b,666)
fmt.Println(len(b),b) //6 [2 3 4 5 555 666]
fmt.Println(cap(b)) //6
//当追加值后切片总长度不大于切片容量,切片值改变,底层数组对应值也跟着变
b[0]=999 //切片修改
fmt.Println(a) //[0 1 999 3 4 5 555 666]
//当追加溢出容量后,会重新申请新的一块内存,就会脱离数组控制,然后扩容至容量二倍,更改切片值,原数组值不再变
b=append(b,777)
fmt.Println(len(b),b) //7 [999 3 4 5 555 666 777]
fmt.Println(cap(b)) //12
b[0]=9999
fmt.Println(b) //[9999 3 4 5 555 666 777]
fmt.Println(a) //[0 1 999 3 4 5 555 666]
// 第二种切片 自己建的
var g =make([]int,3,4)
fmt.Println(g) //[0 0 0]
g=append(g,4)
fmt.Println(g) //[0 0 0 4]
fmt.Println(len(g)) //4
fmt.Println(cap(g)) //4
g=append(g,5)
fmt.Println(len(g)) //5
fmt.Println(cap(g)) //8
}
4.多维切片
package main
import "fmt"
func main () {
//多维切片
// var a [][]string=make([][]string,2,3) // 这个只能初始化外层的切片
// fmt.Println(a) // [[] []]
//
// a[0]=make([]string,2,3) //初始化内层
// if a[0]==nil{ fmt.Println("xxxx")}
// fmt.Println(a) //[[ ] []] a[0]初始化了,默认值为空,明显和a[1]不一样
//多维切片初始化
// var a [][]string=[][]string{{"1","2"},{"3","4"}}
// fmt.Println(a) // [[1 2] [3 4]]
// fmt.Println(len(a)) //2
// fmt.Println(cap(a)) //2
// a[0][1]="999"
// fmt.Println(a) //[[1 999] [3 4]]
// a[1][0]="999"
// fmt.Println(a) //[[1 999] [999 4]]
//循环多维切片
pls := [][]string {
{"C", "C++"},
{"JavaScript"},
{"Go", "Rust"},
}
fmt.Println(pls) //[[C C++] [JavaScript] [Go Rust]]
for _,v:=range pls {
for _,v1:=range v{
fmt.Println(v1)
}
}
}
5.切片的函数传递
package main
import "fmt"
func main () {
//切片的函数传递
var b =make([]int,3,4)
test(b)
fmt.Println(b)
}
func test(b []int) {
b[0]=999
fmt.Println(b)
}
6.变长参数
package main
import "fmt"
//可变长参数
func main() {
test1(1,2,3,4)
//[1 2 3 4]
//[]int
var a =[]int{1,2,4,}
test1(a...) //相当于打散了
//[1 2 4]
//[]int
veggies := []string{"potatoes", "tomatoes", "brinjal"}
fruits := []string{"oranges", "apples"}
food := append(veggies, fruits...)
fmt.Println("food:",food) //food: [potatoes tomatoes brinjal oranges apples]
}
func test1(a ...int) {
fmt.Println(a)
fmt.Printf("%T",a) //看类型
}
7.copy函数
package main
import "fmt"
func main() {
//copy函数
var a =make([]int,3,10000)
a[1]=99
a[2]=888
fmt.Println(a) //[0 99 888]
var b =make([]int,4,4)
b[1]=100
b[3]=300
fmt.Println(b) // [0 100 0 300]
copy(b,a) //拿a来覆盖b
fmt.Println(b) // [0 99 888 0]
//var b =make([]int,2,4)
//b[1]=100
//fmt.Println(b) // [0 100]
//copy(b,a)
//fmt.Println(b) //[0 99]
}