Title

go基础知识三

一.数组

数组是同一类型元素的集合,并且在内存中连续性存放。例如,整数集合 5,8,9,79,76 形成一个数组。Go 语言中不允许混合不同类型的元素,例如包含字符串和整数的数组。(当然,如果是 interface{} 类型数组,可以包含任意类型)

一个数组的表示形式为 [n]Tn 表示数组中元素的数量,T 代表每个元素的类型。元素的数量 n 也是该类型的一部分

//数组:数组是同一类型元素的集合,在内存中连续存放
package main

import "fmt"

func main() {
//1 基本使用:定义
//定义了一个大小为3的int类型数组
//数组在定义阶段,大小和类型就固定了
//var a [3]int   //只定义,申请了三个地址,并没有初始化
//fmt.Println(a)
   //结果:[0 0 0]


//2 使用数组(从0开始,定义了大小为3,就不能超
//var a [3]int
//a[2]=100
//fmt.Println(a)
   //打印结果:[0 0 100]
   
//fmt.Println(a[0])
   //打印结果:0
   

//3 定义并赋初值,需要带上类型
//var a [3]int=[3]int{1,2,3}
//var a =[3]int{1,2,3}
//a := [3]int{1, 2, 3}

//只给第2个位置设为99
//a := [3]int{2:99}
////进阶版
//a := [3]int{2:99,1:88}
//fmt.Println(a)

//4 数组的大小是类型的一部分
//这两个不是一个类型
//var a [2]int
//var b [3]int
//a=b
//fmt.Println(a>b)

//5 数组是值类型(当参数传递到函数中,修改不会改变原来的值)
// go语言中,都是copy传递,将值复制了一份传递过去,修改不会改变原来的值
/*
python中都是引用传递,一切皆对象,就是地址,当做参数传递是把地址传过去了
python中比较特殊:分为可变类型和不可变类型(可变类型改的就是原来的,不可变类型改的是新的)
*/
   
package main

import "fmt"

func main() {
var a [3]int=[3]int{5,6,7}  //赋值
fmt.Println(a)
   // [5,6,7]
test1(a)
fmt.Println(a)
   //[5,6,7] //因为是值传递,这里打印的是初始的设定值
}
   
   func test1(a [3]int) {
a[0]=999
fmt.Println(a)
     // [999,6,7] // 这里打印的是函数test1的值

}
   
//6 数组长度(len)
//var a [3]int=[3]int{5,6,7}
//fmt.Println(len(a))

//7 循环数组
//方式一
//var a [3]int=[3]int{5,6,7}
//for i:=0;i<len(a);i++{
// fmt.Println(a[i])
//}
//方式二
//range:是一个关键字(python中range是一个内置函数)
//var a [3]int=[3]int{5,6,7}
//for i,v:=range a{
// fmt.Println(i) //索引
// fmt.Println(v) //数组的值
//}
//函数如果返回两个值,必须用两个值来接收
//range是关键字,可以用一个值来接收,如果用一个值来接收,接收的结果是索引
//for i:=range a{
// fmt.Println(i) //索引
//}
//只取值,不取索引
//for _,v:=range a{
// fmt.Println(v) //值
//}

//8 多维数组(即一个数组内部可以再放其他数组)
//定义一个二维数组
//var a [3][2]int
   // 打印结果
   //[[0 0][0 0] [0 0]]

//定义并初始化多维数组
var a [3][2]int=[3][2]int{{1,2},{4,5},{9,70}}
//a[1][0]=999
fmt.Println(a)
   // [[0 0] [999 0] [0 0]]

//两种方式循环出二维数组


}

补充:部分数据类型的默认值

    var b int
fmt.Println(b)
//0

var c float32
fmt.Println(c)
//0

var d string
fmt.Println(d)
// 空字符串

var e bool
fmt.Println(e)
//false

 

二. 切片

//切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用。
//切片底层依附于数组
package main

import "fmt"

func main() {
//1 创建切片(基于一个数组创建,先创建一个数组)
//var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
////2 基于数组,切出一部分成为切片
//// []int 中括号中没有东西,就是切片,[]int表示切片类型
//var b []int
//// 没有-1 没有步长
//
//b=a[0:3] //前闭后开,表示从第0个开始切切到第三个但是不包括第三个元素
////b=a[3:6] //前闭后开
////b=a[:] //前闭后开
////b=a[3:] //前闭后开
//fmt.Println(b)
   
// 注意:切片只是指向了原数组,并不是造出一个新的数组
   
////2 使用切片
//fmt.Println(b[0])

//3 切片的修改会影响底层数组,数组的修改也会影响切片
//var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
//var b []int=a[0:3] //前闭后开
//
//fmt.Println(a)
//fmt.Println(b)
//a[0]=999
//b[2]=888
//fmt.Println(a)
//fmt.Println(b)

// 4 切片的长度(len)和容量(cap)
//var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
// //var b []int=a[2:3] //前闭后开

//fmt.Println(len(b))
////切片容量是9,意思是,可以往里追加值,追加成9个
//fmt.Println(cap(b))

   
   ////容量就是原数组的长度呗?答案是不准确,容量是指从切的起始位置到后面的全部长度(比如原数组是[1,2,3,4,5,6,7],切片切的位置是[2:3],则容量为5,即从索引为2的位置到后面的长度)
//b[0]=9999
//fmt.Println(a)
//fmt.Println(b)


//5 追加值
//var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
//var b []int=a[2:3] //前闭后开
//b=append(b,1) // append表示在切片b上追加值,并且返回一个切片,所以需要接收一下
//b=append(b,11,22,33,44,55)
//fmt.Println(len(b)) // 追加后长度变了
//fmt.Println(cap(b)) // 容量不变
//fmt.Println(b)
//fmt.Println(a)     // a也发生了变化
//到了数组的尾部,继续追加值
//b=append(b,999)
//fmt.Println(len(b))
//fmt.Println(cap(b)) //容量是14
////总结1:当切片追加值,超过了切片容量,切片容量会翻倍,在原来容量基础上乘以2
////b=append(b,222,333,444,555,666,7,8)
////fmt.Println(len(b))
////fmt.Println(cap(b)) //容量是14
//
////总结2:一旦超过了原数组, 就会重新申请数组,把数据copy到新数组,切片和原数组就没有关系了
//fmt.Println(a)
//fmt.Println(b)
//a[8]=7777
//fmt.Println(a)
//fmt.Println(b)

//6 通过make创建切片,即定义切片(底层也依附于数组)
//var a []int
//切片零值是什么? nil类型:是所有引用类型的空值
//fmt.Println(a)
//if a==nil{
// fmt.Println("我是空的")
//}

//3是长度,4是容量
//var a []int=make([]int,3,4)
   
//3是长度,3是容量
//var a []int=make([]int,3)
//fmt.Println(a)
//if a==nil{
// fmt.Println("我是空的")
//}
//
//fmt.Println(len(a))
//fmt.Println(cap(a))
//
//a=append(a,55)
//fmt.Println(a)
//fmt.Println(len(a))
//fmt.Println(cap(a))


//6 切片定义并赋初值
//var a []int=[]int{1,2,3}
//fmt.Println(a)
//fmt.Println(len(a))
//fmt.Println(cap(a))

//7 切片是引用类型,当参数传递,会修改掉原来的值
//var a []int=[]int{1,2,3}
//fmt.Println(a)  
   // [1,2,3]
//test3(a)
//fmt.Println(a)
   //[999,2,3]


//8 多维切片
//var a [][]int=make([][]int,2,3)
//fmt.Println(a)
//fmt.Println(a[0]==nil)
////直接给第二层切片赋值会报错
////a[0][0]=999
//// 如何做?(for循环完成初始化)
//需要对第二层切片再做一次初始化
//a[0]=make([]int,2,3)
//a[0][1]=999
//fmt.Println(a)
//a[1][0]=99999

//定义并赋初值用的多
//var a [][]int=[][]int{{1,2,3},{4,5,6,7,7,8}}
   //fmt.Println(a)
   //[[1,2,3] [4,5,6,7,8]]
////跟上面不一样,下面这个是放一个大小为三的数组在里面
//var a [][3]int=[][3]int{{1,2,3},{4,5,6}}
//fmt.Println(a)

//9 切片的copy
//var a []int=make([]int,3,4)
//var b []int=make([]int,2,6)
//a[0]=11
//a[1]=22
//a[2]=33
//b[0]=999
//fmt.Println(a)
//fmt.Println(b)
//目标是b,原切片是a,这样就把a复制给b
//copy(b,a)
//fmt.Println(b)

//10 切片越界
//var a []int=make([]int,3,4)
//a[0]=11
//a[1]=22
//a[2]=33
//
//a=append(a,999)
////中括号取值,只能取到长度值,不能取到容量大小,如果超过长度取值会报错,或者可以在后面追加
//fmt.Println(a[3] )
   
   
   //11 切片循环
   var a []int = make([]int 3,4)
   for i:=0;i<len(a);i++{
       fmt.println(a[i])
  }
   
   //或者
   for i,v := range a{
       fmt.println(i)
       fmt.println(v)
  }

}

func test3(a []int) {
a[0]=999
fmt.Println(a)
}

三. Maps

//maps:go中将key和value关联的内置类型,类似于python中字典, 数据类型是可hash的,以key:value存储,并且value的数据类型是一致的

package main

import "fmt"

func main() {
//1 map的定义和使用
//map[key类型]value类型:key的类型必须可hash,key值:数字,字符串
//map的零值:nil   它是一个引用类型
//var a map[int]string
//fmt.Println(a)
//if a==nil{
// fmt.Println("我是空的")
//}

//2 定义了,没有初始化,使用会导致空指针异常,一种报错
//var a map[int]string
   
//初始化用make
//var a map[int]string=make(map[int]string)
   
////如果有,会修改,如果没有,会放入
//a[1]="lqz"
//a[1]="egon"
//a[2]="99"
//
////a["xx"] key值不能乱写,定义的是什么就是什么
//
//fmt.Println(a)

//3 获取元素
//var a map[int]string=make(map[int]string)
////var a map[int]int=make(map[int]int)
//fmt.Println(a[0]) //取出value值的空值,即空字符串 ""
//fmt.Println(a)

//统一的方案来判断value值是否存在
   

//a[0] 可以返回两个值,一个是value值(可能为空),另一个是true或false
//var a map[int]int=make(map[int]int)
//a[0]=0
//v,ok:=a[0]
//fmt.Println(v)   //这个打印的是value值
//fmt.Println(ok) // 若为false则为空,若为true则为0

//4 map 删除元素(补充:上面写的切片是不能删的,想删需要复制一份再删)
//var a map[int]int=make(map[int]int)
//a[1]=11
//a[2]=22
//fmt.Println(a)
////根据key删(内置函数)
   //delete(a,key:1)
//fmt.Println(a)

//5 map 长度
//var a map[int]int=make(map[int]int)
//fmt.Println(len(a))
//a[1]=11
//a[2]=22
//fmt.Println(len(a))

//6 map 是引用类型
//var a map[int]int=make(map[int]int)
//a[1]=11
//
//test4(a)
//fmt.Println(a)

//7 Map 的相等性
//var a map[string]string=make(map[string]string)
//a["name"]="lqz"
//var b map[string]string=make(map[string]string)
//b["name"]="lqz"
//
////不能这样判断,map只能跟nil比较
   // if a== b //map是引用类型,这样比较的是引用的两个地址,无法比较
//if a==nil {
//
//}

//8 循环map
   // 定义并初始化
var a map[string]string=map[string]string{"name":"lqz","age":"19","sex":"男"}
// 下面这种写法不合理
//for i:=0;i<len(a) ; i++ {
// fmt.Println(a[i])
//
//}

//只能借助range循环
for k,v:=range a{
fmt.Println(k)
fmt.Println(v)
}

// 9 map是无序的(python中字典从3.6以后有序了,3.6之前无序,底层如何实现的,看博客)



}

func test4(a map[int]int) {
a[1]=999
fmt.Println(a)
}

 

 

posted @ 2020-04-25 23:06  Mr江  阅读(152)  评论(0编辑  收藏  举报