0
点赞
收藏
分享

微信扫一扫

golang

niboac 2022-01-27 阅读 6

一、基础

1、声明变量与常量

	(1)变量声明的三种方式
		var i int=16
		var i=16
		i :=16//只能在局部作用域声明变量
	(2)声明常量
		const pi=3.1415926
		const(
		e=2.156132
		E=1.251515
		)
	(3)变量声明注意事项
		var(
		i int//不给初值默认为0
		b bool//默认为false
		)
		//对于这一类的返回值,可以选择忽略,匿名变量
		_,result:=func()
	(4)常量声明注意事项
		const(
		a=100//100
		b	//100
		c	//100
		d	//100
		)
		
		const(
		a=iota//0
		b		//1
		c		//2
		_		
		d		//4	
		)
		const (
		aq,ao=iota+1,iota+4//1,4
		af,as				//**2,5==>iota+1,iota+4->iota=1**
		ap,ah				//3,6
		)

2、基本数据类型

	(1)整型
		包括无符号整型:uint8=>byte,uint16,uint32,uint64
		有符号整型:int8,int16,int32,int64
		特殊类型:
				int=>32位电脑32,64位电脑64
			    uint=>同上
			    uintptr=>用来存放指针
	
	(2)浮点型:float32,float64
	
	(3)bool型:false,true
	
	(4)字符串类型:
		var s string="哈哈哈哈哈哈\n"==>哈哈哈哈哈哈
		var s string=`哈哈哈哈哈哈\r\n`==>哈哈哈哈哈哈哈\r\n
	(5)byte和rune类型
		byte表示字节型,rune表示字符型(可用来表示汉字)
	
	(6)类型转换
		1、T(type)=>转换为t类型
		2、strconv.prase()字符串类型转别的类型
		3、strconv.format()别的类型转字符串类型

3、流程控制

	(1)for循环
		//死循环
		for{}
		//类似while循环
		for i>=10{}
		//添加一句执行语句
		for i:=10;i>=10{}
		//标准for循环
		for i:=0;i<=10;i++{}
		//for-range
		for _,v :=range 数组名称{}
	(2)switch-case
		//类型一
		switch {
		case bool判断:
		case bool判断:
		}
		//类型二
		switch c{	//==>c可以为字符、字符串、整形
		case 'a','b':
		}

4、数组

	(1)定义数组
		//方法一
		var i=[...]int{}
		//方法二
		var i=[4]int{}
	(2)注意
		数组赋值和传参直接传的是值,所以更改的只是一个副本
		数组之间可以进行==和!=的比较

5、切片

	(1)定义
		//方式一:arr维护数组
		arr :=[...]int{1,2,3,4,5}
		slice := arr[a:b:c]//a:起始位置b:长度截至位置c:容量截至位置
		===========>len(slice)=b-a cap(slice)=c-a
		//方式二:make维护数组
		slice :=[]int{11,15,13}
		//方式三:make维护数组
		slice :=make(int,a,b)//a:len b:cap
	(2)切片底层
		//可以看出切片属于引用数据类型,所以不可以直接==比较
		type slice struct{
		array *notInHeap
		len int
		cap int
		}
	(3)切片的容量与长度
		长度:append添加数据时,添加的数据是往len长度之后添加的
		容量:当容量满了之后需要扩容时,将会使用扩容
	newcap := old.cap
	doublecap := newcap + newcap
	//为0的情况下需要使用
	if cap > doublecap {
		newcap = cap
	} else {
		//老的容量小于1024的时候直接扩容为老容量的2倍
		if old.cap < 1024 {
			newcap = doublecap
		} else {
			// Check 0 < newcap to detect overflow
			// and prevent an infinite loop.
			//如果老容量大于1024的话每次扩容为老容量的四分之一
			for 0 < newcap && newcap < cap {
				newcap += newcap / 4
			}
			// Set newcap to the requested cap when
			// the newcap calculation overflowed.
			if newcap <= 0 {
				newcap = cap
			}
		}
	}
	(4)切片追加数据
		slice :=make(int,4,4)
		slice2 :=[]int{1,2,3}
		slice=append(slice,1,2,3,5)
		slice=append(slice,slice2...)
	(5)切片拷贝
		注意:一定要初始化容量大小,拷贝的容量大小是根据len来的
	s :=[]int{8,11,55,15,16}
	var fpx []int=make([]int,5,7)
	ace :=fpx[2:7:7]
	copy(ace,s[:])
	fpx=append(fpx, 99)
	fmt.Println(fpx,s,ace)
	fmt.Println(&fpx[2],&s[0],&ace[0])
	//输出:
	[0 0 8 11 55 99] [8 11 55 15 16] [8 11 55 99 16]
	0xc000010250 0xc00000c330 0xc000010250
		结论:
			在不触发任意一个切片扩容的前提下,操作的还是同一个数组
	
	(6)删除
		切片删除只能根据特性,实际上生成了新的切片并将指针返回去
		var slice=[]int{1,2,3,4,5,6}
		append(slice[:2],slice[3:])

6、map

	(1)定义
		公式 map[key类型]value类型
		//方式一
		var m map[string]int=make(map[string]int,b)//b=>map的长度
		//方式二
		var m=map[string]int{
		"sss":11,
		"ppp":12,
		}
	(2)增删改查
		var m :=make(map[string]interface{},6)
		//增
		m["张三"]=16
		//删
		delate(m,"张三")
		//改
		m["张三"]=18
		//查
		v,b :=m["张三"]//b=true v=18
	(3)注意事项
		map中存切片,若切片发生扩容,地址将发生变化,
		此时map中的切片原地址将发生变化,所以需要及时维护
		var nice =make([]int,1)
		var mc=make(map[string][]int,3)
		nice[0]=12
		mc["zhangzhang"]=nice
		//错误写法
		nice=append(mc["zhangzhang"],13)
		//正确写法
		mc["zhangzhang"]=append(mc["zhangzhang"],13)
		//但此时nice底层的数组已不被map所维护

7、函数

(1)定义

		func (专属函数t type)add(入参a int) (返回值i int){}
		//专属oop函数调用
		type person struct{
		name string
		age int
		}
		func (p person)say(name string,age int){
		fmt.println("i`am---->",p.name)
		}
		//定义一个函数类型的变量
		func add(a int,b int)int{
		retuen 0;
		}
		
		type two func(int,int)int
		var t two
		t=add

(2)应用

		函数可以作为参数,也可以作为一个返回值
		//作为另一个函数的参数
		func add(a int,op func(int,int)int)int{}
		//作为一个返回值
		func acc(a int)(fun(int,int)int){}

(3)匿名函数

		回调函数
		func (a int,b int)int{
		}(5,10)
		闭包=环境+函数
		//其中外层函数指的是环境
		func sum()func(int,int)int{
			var i int
			//内层则是环境
			return func(f,v int)int{
			i+=f^v
			return i
			}
		}
		//使用
		v :=sum()
		v(3,5)

(4)defer

		注意:
			只能执行在函数语句之前,且只作用在最外层函数
			注册时若函数有参数,则要先确定函数的参数值
			执行的时机在return赋值之后,ret之前
func calc(index string, a, b int) int {
	ret := a + b
	fmt.Println(index, a, b, ret)
	return ret
}

func main() {
	x := 1
	y := 2
	defer calc("AA", x, calc("A", x, y))
	x = 10
	defer calc("BB", x, calc("B", x, y))
	y = 20
}
		打印结果:
			A 1 2 3
			B 10 2 12
			BB 10 12 22
			AA 1 3 4

(5)异常处理

		panic()用来抛出异常,类似于java中的throw(不会继续执行)
		recover()可以用来处理异常,要配合defer使用,且在异常之前
	func f2() (x int) {
	defer func() {
		error := recover()
		if error!=nil {
			fmt.Println("f2 error")
		}
	}()
	panic("错了我的宝")
	x=555
	return x
}
		即使捕获到了异常,这里的值也不会正常返回,但会执行下边

8、指针

	(1)make和new
		二者都是用来做内存分配的,make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
		而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

9、结构体

(1)定义

		//定义新类型
		type rune int32
		//起别名
		type i=int
		//定义结构体
		type person struct{
			name string
			age int8
		}

(2)使用

		//生成一个结构体指针类型
		var p = new(person)
		var p = &person{}
		//生成一个普通类型
		var p = person{name:"牛德华",age:12}
		//匿名
		var person struct{name string;age int}

(3)结构体字节对齐

	1、偏移量必须为变量自身的长度的倍数,结构体中第一位无偏移量
	2、若成员变量所占字节长度大于编译器默认对齐长度时取编译器默认对齐长度
	3、结构体整体对齐长度为编译器默认对齐长度的倍数
	4、编译器默认对其长度可更改,64位电脑默认为8字节,32位默认4字节
		//例子
		type person struct{
			name string//占16字节
			age int8//占1字节偏移量16
			sex int32//占4字节,偏移量20,其中空出三字节为了对齐使用
			money int64//占8字节,偏移量24
			b bool//占1字节,偏移量32
			//字节对齐,空出7字节
		}
		//最终内存分配结果:(n*16)|axxx|ssss|mmmm|mmmm|bxxxxxxx
	5、总结:多数情况下,尽量将所占内存小的往前边写

(4)结构体成员嵌套与匿名

		//嵌套
		type person struct{
		name string
		age int8
		}
		type student struct{
		p person
		schoolName string
		}
		//匿名
		type person struct{
		string //使用:person.string
		int
		}

(5)继承

		type animal struct{
		name string
		age int8
		}
		type dog struct{
		animal
		color string
		}
	注意:
		继承的方法名,参数,返回值必须要相同

(6)封装

	在成员变量的首字母小写时实现封装,此成员变量只有本包可见

(7)json序列化与反序列化

	序列化:data, err := json.Marshal(c)
	反序列化:err = json.Unmarshal([]byte(str), c1)
	注意:在使用json函数时,一定要确保属性字段可见才可以获取到

(8)为结构体定义tag

		type person struct{
		Id int `json:"Id" ps:"hhshsh"`
		}
	后边反引号组成的便是tag,可以多个可以一个,必须严格遵守此格式

10、导包

(1)常见错误

经常会遇到导入自己的包报错的情况,或者没有报错但是提示找不到包,这个时候需要配置

![在这里插入图片描述](https://img-blog.csdnimg.cn/6722e02d7f624735bca1e2c2cf4884bd.PNG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAYXBwbGVfNTIwNjYwOTI=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
执行go mod init
![在这里插入图片描述](https://img-blog.csdnimg.cn/e76896c969fd4975b7a38dabdad694de.PNG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAYXBwbGVfNTIwNjYwOTI=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)

(2)init函数

	在go语言中,一个go文件的初始化从init()函数开始
	1、首先会根据import形成一个树形结构,从最后导入的依赖的init开始执行
	2、init函数不能主动调用,在程序执行时会自动调用
	3、init函数没有参数也没有返回值

11、接口

12、反射

举报

相关推荐

0 条评论