读书笔记-Golang从入门到进阶实战

108 阅读9分钟

Golang从入门到进阶实战

1.基本语法(基本数据)

1.1变量定义

1.1.1 标准格式

Go 量声明格式为:

var 变量名 变量类型

变量声明 关键字 var 开头,后置变量类型,行尾无须分号。

 var a 
 var b string 
 var c [] float32 
 var d func() bool 
 var e struct{ 
 x int 
 }
1.1.2 批量格式
var ( 
a int 
b string 
c [] float32 
d func () bool 
e struct { 
x int 
}
)

1.2变量赋值

1.2.1 标准格式

var 变量名类型=表达式 例如:游戏中,玩家的血量初始值为 100 。可以这样写:

var hp int = 100
1.2.2 编译器推导类型的格式

var hp = 100 等号右边的部分在编译原理里被称做“右值”。 下面是编译器根据右值推导变量类型完成初始化的例子

 var attack = 40 
 
 var defence = 20 
 
 var damageRate float32 = 0 . 17 
 
 var damage= float32 (attack-defence) * damageRate 
 
 fmt.Println(damage)
1.2.3 短变量声明并初始化

var 的变量声 明还有 种更为精简的写法,例如:

hp := 100

这是 Go 语言的推导声明写法,编译器会自动根据右值类型推断出左值的对应类型。

1.2.4 匿名变量

在使用多重赋值时,如果不需要在左值中接收变量 可以使用匿名变量。

 func GetData() (intint) { 
 	return 100 , 200 
 } 
 
 a , _: = GetData() 
 
 _, b : = GetData() 
 
 fmt . Println(a , b)

1.3数据类型

Go 语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型 字符串外,还有

切片、结构体 函数、 map 通道( channel )等。 Go 语言的基本类型和其他语言大同小异,切片类型有着指针的便利性,但 比指针更为安全 很多高级语言都配有切片进行安全和高效率的内 存操作。

结构体是 Go 语言基 的复杂类型之一,后面会用单独的一章进行讲解。

函数也是 Go 语言的 种数据类型,可 对函数类型 变量进行赋值和获取,函数特

性较多,将被放在独立章节讲解 。

map和切片是开发中常见的数据容器类型。

通道与并发息息相关 读者会在第 章了解通道的细节。

  1. 整型。
  2. 浮点型。
  3. 布尔
  4. 字符串
  5. 字符
  6. 切片-能动态分配的空间

切片是一个拥有相同类型元素的可变长度的序列 切片的声明方式如下: T是切片元素类型,可以使整型,浮点,切片,map,函数等。

var name [] T 
 a := make([]int , 3) 
 
 a [O] = 1 
 a [1] = 2 
 a [3] = 3

解释:1.创建类型为Int,容量为3的切片。

  1. 给3个切片赋值。

1.4数据类型转换

Go 语言使用类型前置加括号的方式进行类型转换 一般格式如下 :

T(表达式)

代表要转换的类型。表达式包括变量、复杂算子和函数返回值等。

注意:类型转换 ,需要考虑两种类型的关系和范围,是否会发生数值截断等 。

1.5指针

指针概念在 Go 语言中被拆分为两个核 概念

1.类型指针,允许对这个指针类型的数据进行修改。传递数据使用指针,而无须拷贝数据。类型指针不能进行偏移和运算。

2.切片,由指向起始元素的原始指针、元素数量和容量组成。

ptr : = &v

v的类型为 T,

其中V代表被取地址的变量,被取地址V使用ptr变量进行接收, prt的类型就为"*T",

称做T的指针类型,"*"代表指针。

1.5.1使用指针变量获取命令行的输入信息
1.5.2创建指针的另外一种方法new()
Go 还提供了另外 种方法来创建指针变 ,格式如下: 

new(类型 )

一般这样写:

str := new(string)

*str = "ninja"

fmt.Println(*str)

new ()函数可以创建一个对应类型的指针,创建过程会分配内存。被创建的指针指向的值为默认值。

1.6变量的声明周期

1.6.1 栈空间
1.6.2 堆空间

1.7 字符串

1.7.1 保存格式

字符串一般utf-8保存, 一个汉字占用3个字符。

1.7.2 遍历字符

以ascii打印字符。

theme :="狙击 start"
for i := O; i < len(theme) ; i++ { 
    fmt . Printf ("ascii %c %d\n ”, theme [i] , theme[i])
}

打印汉字的时候就乱码。

以unicode打印字符。

theme := "狙击 start"

for _,s := range theme{

	fmt.Printf("Unicode: %c %d\n",s,s)

} 

就会以正常汉字打印了。

1.7.3 总结:

• ASCII 字符串遍历直接使用下标

• Unicode 字符串遍历用 for range

1.7.4 字符串拼接
hammer "吃我一锤"
sickle "死吧”
//声明字节缓
var stringBuilder bytes.Buffer 
//把字符串写入缓冲
stringBuilder.WriteString(hammer) 
stringBuilder.WriteString(sickle) 
//将缓冲 字符串形式输出
fmt.Println(stringBuilder.String())
1.7.5 格式化

预留

1.7.6 base64 ini文件读取写入操作等
1.7.7 别名

2.容器:存储和组织数据的方式

本章将以实用为目的,详细介绍数组、切片、映射,以及列表的增加、删除、修改和遍

历的使用方法

2.1 数组-固定大小的连续空间

2.1.1 声明:

var 数组变量名[元素数量]T

· 数组变量名 数组声明及使用时的变量名。

· 元素数量 数组的元素数量。可以是一个表达式,但最终通过编译期计算的结果必须是整型数值。也就是说,元素数量不能含有到运行时才能确认大小的数值

· T 可以是任意基本类型,包括 为数组本身。但类型为数组本身时,可以实现多维数组。

var team [3]string  //将 team 明为包含3个元素的字符串数组。
2.1.2 初始化

定义时初始化:

var team [3]string{"hammer","soldier","mum"}

遍历初始化:

var team [3]string
team[0] = "hammer"
team[1] = "soldier" 
team[2] = "mum" 

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

2.2 切片(slice)-动态分配大小的连续空间

2.3 映射(map)-建立食物关联的容器(无序的)

  1. 一般用法
//使用时, 需要手动使用 make创建。如果不创建使用map类型,会触发岩机错误。
scene := make(map[string]int)  
//向map中加入映射关系,写法和数组一样,key可以是除函数外的任意类型。
scene ["route"] = 66 
//查找map中的值。
fmt.Println(scene["route"])
//查找一个不存在的值,会返回ValueType的默认值
v := scene["route2"] 
fmt.Println(v)
  1. 判断值是否在map中有固定用法:
v,ok := scene ["route"]

在默认获取键值的基础上,多取了一个变量 ok 可以判断键 route 是否存在于 map 中。

  1. 声明时填充内容的方式:
m := map[string]string{
	"W":"forward", 
	"A":"left", 
	"D":"right", 
	"S":"backward",
}

这种情况可以不是用make。

  1. 遍历map。

可是使用for range

  1. 需要在多进程或者多线程中使用的map——sync.Map

2.4 列表(list)-可以快速增删的非连续性空间的容器

  1. 双链表支持从队列前方或后方插入元素,分 对应的方法是 PushFront和PushBack。
  2. 初始化列表(定义)

通过container/list 包的New方法初始化list

变量名 := list.New()

通过声明初始化list

var 变量名 list.List
  1. 添加元素
//创建一个列表示例
l := list.New()
//将fist字符串插入到列表尾部,此时列表是空的,插入后只有一个元素。
l.PushBack("fist")
//将67放入列表,67将被放在fist的前面。
l.PushFront(67)
  1. 还有很多方法后边研究。

3.流程控制

4.函数

4.1 声明形式

func 函数名(参数列表)(返回参数列表){
	函数体
}

func foo ( a int, b string ) int
//参数类型简写, 返回int类型
func add (a,b intint { 
	return a + b 
}

//返回多个值
func swap(x, y string) (string, string) {
   return y, x
}        

4.2 函数变量

Go 语言中, 函数也是一种类型,可以和其他类型一样被保存在变量中。下面的代码定义了一个函数变量f,并将一个个函数名 fire()赋给函数变量f,这样调用函数变量f时,实际调用的就是fire()函数,代码如下:

package main 

import (
	"fmt"
)

func fire() { 
	fmt.Println("fire") 
} 

func main() { 
	var f func() 
	f = fire 
	f () 
}

4.3 匿名函数

定义: 匿名函数就是没有名字的普通函数定义.

func (参数列表) (返回参数列表){
	函数体
}

4.3.1 在定义时直接调用匿名函数

func(data init) { 
	fmt.Println (”hello”, data) 
} (100)

4.3.2 将匿名函数赋值给变量

//将匿名函数体保存到f()中
f := func(data int){
    fmt.Println("hello",data)
}
//使用f()调用
f(100)

4.3.3 匿名函数作为回调函数

//对切片进行遍历操作,遍历中访问每个元素的操作使用匿名函数来实现

//遍历切片的每个元素,通过给定函数进行元素访问
func visit(list []int, f func(int)){
    for _,v := range list{
        f(v)
    }
}

func main() {
    //使用匿名函数打印切片内容
    visit([]int{1,2,3,4}, func(v int){
        fmt.Println(v)
    })
}

4.3.4 使用匿名函数实现操作封装

5.函数类型实现接口

6.闭包

闭包=函数+引用环境

7.可变参数

//v 为可变参数变量, 类型为[]T, 也就是拥有多个T元素的T类型切片.
//T为可变参数类型,当T为interface{}时,传入的可以是任意类型.
func 函数名 (固定参数列表, v ... T) (返回参数列表){
    函数体
}

7.1 所有参数都是可变参数:

//打印函数定义如下:
func Println(a ... interface{}) (n int, err error){
    //略
}

//调用时,参数可以是任意类型.
fmt.Println(5,"hello". &struct{a int}{1}, true)

7.2 部分参数为可变参数

func Printf(format string, a ...interface{}) (n int, err error){
    //略
}

//调用时,第一个参数必须为string
fmt.Printf("pure string\n")
fmt.Printf("value: %v %f\n",true, math.Pi)

8.延迟执行语句

​ Go 言的 defe 语句会将其后面跟随的语句进行延迟处理。在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语旬,最先被执行。

(内心独白:好鸡肋的作用,按c语言编程习惯,这个就是个无用的东西.)

8.1使用延迟语句在函数退出时释放资源.

9.处理运行时发生的错误

10.宕机(panic)

10.1 手动触发宕机

func main(){
    panic("crash")
}
//代码运行崩溃并输出如下:
panci: crash
goroutine 1 [running]:
main.main()
main.go:5 +0x6b

10.2 在运行依赖的必备资源时主动触发宕机

10.3 在宕机时触发延迟执行语句

func main(){
    defer fmt.Println("宕机后要做的事情1")
    defer fmt.Println("宕机后要做的事情2")
    panic("宕机")
}

11.宕机恢复

5.结构体

定义: 一个复合类型. 没有类等面向对象的概念.

type 类型名 struct{
    字段1   字段1的类型
    字段2   字段2的类型
    ...
}
5.1 实例化结构体
var test T

T为结构体类型. test为结构体的实例.

5.1.1 创建指针类型的结构体