这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
前言
大家好呀,这是我参加青训营伴学笔记创作活动的第 1 天,如存在问题,烦请各位斧正!
Go语言入门
Go的诞生
Go语言最初由Google公司的三个大牛于2007年开始设计发明,他们最终的目标是设计一种适应网络和多核时代的C语言。
1)从各种角度看,Go语言确实是从C语言继承了诸多编程思想。
2)但它舍弃了部分C的设计、重新设计了C语言中部分不太合理运算符的优先级,
并在很多细微的地方都做了必要的打磨和改变。
Go能做什么
1)区块链研发
2)服务端: C相当它来讲,开发效率低、运维难度大。
Go相当C有很大优化,并且Go语言据处理和大并发处理的能力非常突出。
3)游戏软件工程: 游戏数据通道会使用Go语言。
4)分布式/云计算软件: 如盛大云CDN、京东分布式文件系统。
Go的优点
1、高性能、高并发 | 2、语法简单、学习曲线平缓 |
3、丰富的标准库 | 4、完善的工具链 |
5、静态链接 | 6、快速编译 |
7、跨平台 | 8、垃圾回收 |
Go的开发环境
我个人是先安装了Goland,然后使用Goland安装了Go1.19。
具体版本各位自行选择,如有教程需要,可以自行搜索,不过多赘述。
Go与面向对象
1)面向对象:Go可以将函数绑定在结构体上;
2)面向过程:go的结构体不支持继承(但支持结构体的嵌套/组合)。
基本结构
func main(){
...
}
基本数据类型
基本分类
1)布尔型:布尔型的值只可以是常量 true 或者 false。
2)数字类型:整型 int 和浮点型 float等。
3)字符串类型:Go 的字符串是由单个字节连接起来的。
Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。
4)派生类型:
(1) 指针类型(Pointer)(2) 数组类型 (3) 结构化类型(struct) (4) Channel 类型
(5) 函数类型 (6) 切片类型 (7) 接口类型(interface) (8) Map 类型
变量的声明
1、单个变量声明
1)标准声明方式:定义并赋值,注意类型是后置的:
var a int = 22)推断声明方式:Go 支持变量类型自动推断,即赋值时可以省略类型信息:
var a = 2(这种方式仅限定义时赋值的方式)3)简短声明方式:定义时赋值的方式也可以通过":="符号来声明,比如:
a := 2
2、批量声明
1)批量声明:多用于全局变量。举例:
var (
temp1 string
temp2 int
)
2)同类型批量声明,举例:
var a,b int3)批量简短声明,举例:
a,b := 1,"string"3、匿名变量
1)匿名变量不占用内存空间,不会分配内存,所以可以多次声明。
它的使用场景多为,为了忽略某些值,如下,为了让age拿到第二个返回值用到了匿名变量:
func foo() (string, int) {
return "payne", 20
}
func main() {
_, age := foo()
}
4、常量
1)它的声明与变量的声明基本一致,将关键字var替换成了const。比如:
consta int=1
基本类型
类型
描述
uint8 / uint16 / uint32 / uint64
无符号 8 / 16 / 32 / 64位整型
int8 / int16 / int32 / int64
有符号8 / 16 / 32 / 64位整型
float32 / float64
IEEE-754 32 / 64 位浮点型数
complex64 / complex128
32 / 64 位实数和虚数
byte/rune
类似 uint8 / int32,内置的两个字符类型
bool
uintptr
无符号整型,用于存放一个指针
指针
1)声明指针:
var name *type2)取地址符&:取出变量a的地址赋值给ip:
ip =&a3)零值:它属于引用类型,它的初始值为 nil。
4)取值:使用*指针名来取值。
数组
1、数组声明
Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:
var name [SIZE] type(比如:varbalance [10]float32)2、初始化数组
1)可以直接进行初始化:
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}(若声明则指定值,依旧可以使用:=)2)数组长度不确定:编译器通过元素个数自行推断数组长度,在[ ]中填入"..."。
3、go中数组名的意义:
1)C中数组名在本质上是数组中第一个元素的地址,但go中只表示整个数组。
2)所以在go中一个数组变量被赋值或者被传递的时候实际上就会复制整个数组。为了避免这种开销,往往需要传递一个指向数组的指针。
4、数组指针
1)存在数组a,则
var ap = &a2)除了避免传递数组时浪费空间,还可以用数组指针来foreach迭代:
for i,v :=range b { ... }
结构体
结构体中可以定义多个不同的数据类型。
1、声明结构体
1)需要使用type和struct,type用于设定结构体的名称,struct用于定义一个新的数据类型。具体结构如下:
type 结构体名称 struct{
名称 类型 // 成员或属性
...
}
2)结构体可以定义在函数内部或函数外部(与普通变量一样),定义位置影响到结构体的访问范围
(1)如果结构体定义在函数外面,结构体名称首字母是否大写影响到结构体是否能跨包访问。
(2)如果结构体能跨包访问,属性首字母是否大写影响到属性是否跨包访问。
2、声明结构体变量
1)可以直接给结构体多个属性赋值:
var peo People// 按照结构体中属性的顺序进行赋值,可以省略属性名称
peo = People{"smallming", 17}
peo =People{Age:18, Name:"LiXC"}2)通过结构体变量名称获取到属性进行赋值或查看值。
peo.Name="smallming"
fmt.Println(peo.Age)3、结构体指针
由于结构体是值类型,在方法传递时希望传递结构体地址,可以使用时结构体指针完成。
1)可以直接声明结构体指针并赋值:
var peo *People
peo = &People{"smallming", 17}2)可以结合new(T)函数创建结构体指针:
peo := new(People)3)使用结构体指针引用属性依旧可以只是用".",如:
peo.Name = "smallming"
字符串
1、概述
1)Go 的字符串内部实现使用 UTF-8 编码,
2)Go 这样做的好处是① 减少内存和硬盘空间占用;② 不需要对使用 UTF-8 字符集的文本进行编码和解码。
3)Go 的字符串的值为双引号""中的内容。 而若是不想转义、即非解释型字符串,则使用反引号
str := `xxx`。4)Go 的字符串是一种值类型且值不可变,即字符串是字节的定长数组。
5)一般的比较运算符(==、!=、<、<=、>=、>)通过在内存中按字节比较来实现字符串的对比。
2、Go字符串底层
1)Go语言字符串本质是一个结构体,它的底层结构在reflect.StringHeader中定义,具体如下:
type StringHeader struct {
Data uintptr // 字符串指向的底层字节数组
Len int // 字符串的字节的长度。
}
2)Go语言的字符串中可以存放任意的二进制字节序列,而且即使是UTF8字符序列也可能会遇到坏的编码。
如果遇到一个错误的UTF8编码输入,将生成一个特别的Unicode字符‘\uFFFD’,显示为黑色菱形内部一个白色问号。
基本控制结构
选择语句
1、if-else语句
if 布尔表达式 {
...
} else {
...
}
1)在 Go 中,布尔表达式的括号是可选的,我们也建议不要使用括号。
2)但是大括号不可以省略,即使只有一条语句。
2、switch语句
1)其中的变量v可以是任何类型。val1和val2可以是同类型的任意值,类型不局限为常量或者整数,或者表达式(结果为相同类型)。
switch v {
case val1:
...
case val2:
...
default:
...
}
2)甚至可以不写v,直接将val1等写为布尔类型表达式,就能代替多个if-else了。
3)要想跳转到下一个 case,可以在一整个case的末尾使用 fallthrough 关键字:(必须在末尾)
case 100:
... // 一些语句
fallthroughcase 200:
...
循环语句
go中只有for循环:
1)与普通for循环一样:
for init; condition; post {}2)与while循环一样:
for condition{}3)与for(;;)循环一样:
for{}4)迭代:for循环还可以直接使用range对slice、map、数组以及字符串等进行迭代循环,这之中也可以使用匿名变量来忽略一些值:
for _, value := range oldmap { }
控制语句
1)break:中断跳出循环或者switch语句
2)continue:跳过当前循环的剩余语句,然后继续下一轮循环