Golang基础

GO基础

Golang内置类型和函数
1.1 内置类型

1.1.1 值类型

bool
int8,int16,int32,int64
uint8,uint16,uint32,uint64
float32,float64
string
array  ---固定长度的数组

1.1.2 引用类型

slice     --- 序列数组
map       --- 映射
chan      --- 管道
1.2 内置函数
append          	-- 用来追加元素到数组、slice中,返回修改后的数组
close				-- 用来关闭channel
delete          	-- 从map中删除key对应的value
panic				-- 停止常规的goroutine(panic和recover:用来做错误处理)
recover				-- 允许程序定义goroutine的panic动作
real				-- 返回complex的实部
imag				-- 返回complex的虚部
make				-- 用来分配内存,返回Type本身(只能应用于slice,map,channel)
new					-- 用来分配内存,主要用来分配值类型,比如int、struct。返回指向type的指针
cap					-- capacity是容量的意思,用于返回某个类型的最大容量(只能用于切片和map)
copy				-- 用于复制和连接slice,返回复制的数目
len					-- 长度,
print、println		-- 底层打印函数,在部署环境中建议使用fmt包
运算符

GO语言内置的运算符有:

  • 算术运算符:“+”、“-”、“*”、“/”、“%”
  • 关系运算符:“==”、“!=”、“>”、“>=”、“<”、“<=”
  • 逻辑运算符: “&&”(如果两边的操作都是true,则为true,否则为false)、“||”(如果两边的操作数有一个true,则为true,否则为false)、“!”
  • 位运算符(下图1)
  • 赋值运算符(下图2)
    在这里插入图片描述

在这里插入图片描述

变量和常量

const 同时声明多个常量时,如果省略了值则表示和上面一行的值相同

func main(){
	const (
		a = 100
		b
		c
	)
	fmt.println("c=",c)
}


结果:b=100,c=100
数组

1、概念:是同一种数据类型的固定长度的序列;
2、定义:var a [len]int ⇒ var a [3]int;数组长度不能变
3、访问越界:如果下标在数组合法范围外,则触发访问越界,会panic
在这里插入图片描述
4、数组是值类型,赋值和传参会赋值整个数组,而不是指针。因此改变副本的值,不会改变本身的值;

切片Slice

一、概念
1、概念:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递;
2、切片的长度是可以改变的,因此,切片是一个可变的数组;
3、定义:var a []类型 ====》var a []string
4、slice并不是数组或者数组指针,它通过内部指针和相关属性引用数组片段,以实现变长方案
5、当声明一个数组时,如果不指定该数组的长度,则该类型为切片
6、如果slice == nil,那么len、cap结果都等于0
7、cap可以求出slice最大扩张容量,不能找过数组限制;0<=len(slice)<=len(array),array是slice引用的数组
8、切片本身并不是动态数组或者数组指针。它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一个只读对象,其工作机制类似数组指针的一种封装。

切片Slice源码的数据结构

type slice struct{
	array unsafe.Pointer//指向数组的指针
	len   int    //当前切片的长度
	cap   int	//当前你切片的容量。cap总是大于len的
}

二、声明方式
1、未指定大小的数组来定义切片;

定义切片 var identifity []int 
或者简单定义:identifity := []int{}

定义数组 var identifity [5]int
[]没有声明长度说明这是一个切片,而不是一个数组,数组声明是必须指定长度的

这种方式只声明不初始化,默认为nil(没有分配内存):len=0,cap=0,slice=[]

在这里插入图片描述
2、声明一个拥有初始长度或规定容量的切片,使用make()函数来创建切片

var slice []int = make([]int,len,cap)
或者 slice := make([]int,len,cap)

len是数组的长度也是切片的初始长度
cap为可选参数,如果cap不写,则默认cap=len


这种方式创建切片,切片被系统自动初始化为0,不是nilmake函数为其分配了内存空间

在这里插入图片描述
三、切片初始化
1、声明的时候同时初始化

s := []int{1,2,3}

2、用数组初始化切片

    array := [5]int{0, 2, 3, 4}
	slice := array[:3]
	fmt.Println("slice=", slice)
	fmt.Println("array=", array)
	fmt.Printf("len(slice)=%v,cap(slice)=%v", len(slice), cap(slice))

在这里插入图片描述
slice[6:8] 表示下标从第6位到第7位,len=2,cap=4
slice[:6:8] 表示slice内容是从-5,len为6 ,cap为8
slice[6:8:8] 表示slice内容为第6位-第8位,len=8-6,cap=8-6

3、切片的内存布局
读写操作目标还是底层数组切片本身就是一个引用

    data := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	slice := data[1:4] //[2,3,4]
	slice[0] += 10
	slice[1] += 20
	fmt.Println("slice = ", slice)
	fmt.Println("data = ", data)


结果:
slice =  [12 23 4]
data =  [1 12 23 4 5 6 7 8 9]

对切片内容的改变实际上改变的是所引用的数组

五、append()和copy()
1、append()实现切片追加

var numbers []int = make([]int, 3, 5)
	fmt.Printf("numbers=%v,len(numbers)=%v,cap(numbers)=%v\n", numbers, len(numbers), cap(numbers))

	num := append(numbers, 1, 2)
	fmt.Printf("num=%v,len(num)=%v,cap(num)=%v\n", num, len(num), cap(num))

	num[2] = 200
	fmt.Printf("num=%v,len(num)=%v,cap(num)=%v\n", num, len(num), cap(num))
	num1 := append(numbers, 1, 2, 3)
	fmt.Printf("num1=%v,len(num1)=%v,cap(num1)=%v\n", num1, len(num1), cap(num1))

	num1[2] = 100
	fmt.Printf("num1=%v,len(num1)=%v,cap(num1)=%v\n", num1, len(num1), cap(num1))

	fmt.Printf("numbers=%v,len(numbers)=%v,cap(numbers)=%v\n", numbers, len(numbers), cap(numbers))

结果

numbers=[0 0 0],len(numbers)=3,cap(numbers)=5
num=[0 0 0 1 2],len(num)=5,cap(num)=5
num=[0 0 200 1 2],len(num)=5,cap(num)=5

num1=[0 0 200 1 2 3],len(num1)=6,cap(num1)=10//超出了数组容量,切片扩容1倍

num1=[0 0 100 1 2 3],len(num1)=6,cap(num1)=10 //新的底层数组

numbers=[0 0 200],len(numbers)=3,cap(numbers)=5//append超出切片容量之后,会重新分配底层数组,修改值不会在影响原始的numbers本身,

2、copy()切片的拷贝
浅拷贝:源切片和目的切片共享同一底层数组空间,源切片修改,目的切片同样被修改
深拷贝:源切片和目的切片各自都有彼此独立的底层数组空间,各自的修改,彼此不受影响

浅拷贝

   slice1 := make([]int, 5, 5)
   slice2 := slice1
   slice1[1] = 1
   fmt.Println(slice1)
   fmt.Println(slice2)

结果:
[0 1 0 0 0]
[0 1 0 0 0]

深拷贝

	data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	fmt.Println("data = ", data)
	
	s1 := data[8:]
	s2 := data[:5]
	fmt.Println("s1=", s1)
	fmt.Println("s2=", s2)

	copy(s1, s2)
	fmt.Println("s1=", s1)
	fmt.Println("s2=", s2)

	fmt.Println("data=", data)

结果:
data =  [0 1 2 3 4 5 6 7 8 9]
s1= [8 9]
s2= [0 1 2 3 4]
s1= [0 1]
s2= [0 1 2 3 4]
data= [0 1 2 3 4 5 6 7 0 1]

六、GO切片扩容策略
如果切片的容量小于1024个元素,于是扩容的时候就翻倍增加容量。
一旦元素个数超过1024个元素,那么增长因子就变成1.25,即每次增加原来的四分之一;

注:扩容扩大的容量都是针对原来的容量而言的,而不是针对原来的数组长度而言的;

七、指针
1、&(取地址)和*(根据地址取值)
2、

对变量进行取地址(&)操作,可以得到这个变量的指针变量;
指针变量的值是指针地址
对指针变量进行取值(*)操作,可以获得指针变量指向原变量的值;

a := 10
b := &a
fmt.Printf("a的地址%p,type为%T\n", &a, a)
fmt.Printf("b的地址%p,type为%T,b的值为%v", b, b, *b)

结果:
a的地址0xc0000aa058,typeint
b的地址0xc0000aa058,type*int,b的值为10

3、空指针
当一个指针被定义后没有分配到任何变量时,值为nil;

var p *string
fmt.Printf("p的值是%v\n", p)

结果:
p的值是<nil>

八、Map
1、概念:Map是一种无序的基于key-value的数据结构,Go语言中的map类型是引用类型,必须初始化才能使用
2、定义:map[keyType]valueType

用make函数来分配内存:make(map[keyType]valueType,cap) ====》map(map[string]string,8)

3、 初始化

1make()初始化
	scoreMap := make(map[string]string, 8)
	scoreMap["小名"] = "90"
	scoreMap["hha"] = "30"
	fmt.Println(scoreMap)
	fmt.Printf("score的type为%T", scoreMap)

2、也可以在声明时填充数据
	userMap := map[string]string{
		"username": "duanjiaqi",
		"age":      "18",
	}
	fmt.Println(userMap)

4、遍历map

	scoreMap := make(map[string]string)
	scoreMap["xiaoming"] = "90"
	scoreMap["xioabai"] = "30"

	for k, v := range scoreMap {
		fmt.Println(k, v)
	}

结果:
xiaoming 90
xioabai 30

5、delete()删除键值对
delete(map,key) map:要删除键值对的map;key:要删除键值对的键名

    scoreMap := make(map[string]string)
	scoreMap["xiaoming"] = "90"
	scoreMap["xioabai"] = "30"
	delete(scoreMap, "xiaoming")
	for k, v := range scoreMap {
		fmt.Println(k, v)
	}

结果:
xioabai 30

九、结构体
1、定义方式

type 类型名 struct{
	字段名  字段类型   //结构体中的字段名必须是唯一的
	字段名  字段类型
	...
}

2、结构体实例化
var 结构体实例 结构体类型

type person struct {
		name string
		city string
		age  int
	}

	var p person
	p.name = "hah"
	p.city = "洪洞"
	p.age = 18
	fmt.Println(p)
	fmt.Println(p.name)
	fmt.Printf("p的值为%#v", p)

结果:
{hah 洪洞 18}
hah
p的值为main.person{name:"hah", city:"洪洞", age:18}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值