【原创】 第二十一章、ORM
21 04 2022

    第二十一章、GORM

        一、ORM介绍

            1.1 Gin框架简介

            中文官方文档:https://gorm.io/zh_CN/

            GORM是Golang目前比较热门的数据库ORM操作库,对开发者也比较友好,使用非常方便简单,使用上主要就是把struct类型和数据库表记录进行映射,操作数据库的时候不需要直接手写Sql代码,这里主要介绍MySQL数据库。

                image.png

            1.2 安装

            go get gorm.io/gorm                 安装最新版本  go get -u gorm.io/gorm

            go get  gorm.io/driver/sqlite      安装最新版本  go get -u gorm.io/driver/sqlite


            1.3 ORM优缺点

            优点:提高开发效率

            缺点:牺牲执行性能、牺牲灵活性、弱化了开发者的SQL能力


        二、CURD操作

            2.1 链接数据库

            image.png


            image.png


            image.png


            2.2 创建记录

            image.png

            image.png

            用指定的字段创建记录

            image.png

            创建一个记录且忽略传递的字段值,创建结构体中 Omit()没有指定的字段值

            image.png

            批量插入数据,将一个slice传给Create方法,GORM会生成一条单独的SQL语句插入所有数据,并填写回主键的值,钩子方法也会被调用

            image.png

            分批插入数据

            image.png

            image.png


            2.3 默认值

            image.png

            案例演示:

            image.png

            image.png


            2.4 查询

            image.png

            image.png

            


            1.5 约定

            GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAtUpdatedAt 字段追踪创建、更新时间

            遵循 GORM 已有的约定,可以减少您的配置和代码量。如果约定不符合您的需求,GORM 允许您自定义配置它们


            



【原创】 第二十章、gin框架
19 04 2022

第二十章、Gin框架

        一、Gin框架介绍

            1.1 Gin框架简介

            Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 httprouter,速度提高了 40 倍。 如果您需要性能和良好的生产力,您一定会喜欢 Gin。

        二、快速入门

            2.1 下载并安装gin

            go get -u github.com/gin-gonic/gin

            2.2 gin渲染HTML

            image.png

            image.png


            终端curl 命令发送请求

            image.png

            2.3 自定义模板函数

            image.png

            image.png

            image.png

            2.4 静态文件处理

            image.png

            image.png

            image.png

            2.5 使用模板继承

            image.png

            image.png


            

            以下模板继承来自于网络其他方式:

            header文件:

            image.png


            footer文件:

            image.png

    

            extends文件:

            image.png

            

            代码如下:

            image.png



        三、gin框架返回数据

            3.1 获取URL参数

            3.1.1 通用处理方式Handle()方式

            image.png


            3.1.2 分类处理engine.GET()        engine.POST(),POST表单默认解析方式x-www-form-urlencoded或from-data格式的参数

            image.png

            image.png

            image.png


            3.2 多数据格式返回请求结果

            image.png


            3.3 表单实体绑定

            image.png

            image.png

            image.png

            image.png


            image.png

            3.4 Any路由的使用

            image.png

            3.5 文件上传

            3.5.1 单文件上传

            image.png

            3.5.2 多文件上传

            image.png

            image.png

            3.6 为不存在的路由配置处理函数

            image.png

            image.png

            image.png

            3.7 日志记录进文件

            image.png

            image.png

            


        四、重定向

           image.png

             4.1 HTTP重定向

            image.png

             4.2 路由重定向

            image.png


        五、路由分组

            4.1 路由分组

            image.png

            image.png

                  image.png


            image.png

            4.2 简化路由分组

            image.png


        五、中间件

            5.1 中间件

            image.png

            image.png

            

            案例演示一,所有API共用中间件:

            image.png

            案例演示二,单独一个API使用中间件方式:

            image.png

            image.png


            5.2 context.Next函数,将中间件代码一分为二执行,执行完成相关调用以后回来继续context.Next()后面的处理函数

            image.png

            案例演示:

            image.png

            image.png

            

            image.png


            5.3 context.Abort函数,阻止调用处理函数

            image.png

            image.png

            页面没有反馈,空白

            image.png

            5.5 context.Abort函数和context.Next函数应用

            image.png


            5.6 路由组注册中间件

            image.png

            5.7 中间件注意事项

            image.png






【原创】 第十九章、go模板渲染
13 04 2022

第十九章、Go模板渲染

        一、Go原生模板渲染

            1.1 Go原生模板解析、模板渲染

            image.png

            image.png

            image.png

            1.2 模板语法

            image.png

            image.png

            image.png

            多个变量渲染

            image.png

            image.png


            1.3 模板中的注释

            image.png

            image.png


            1.4 pipeling

            image.png

            1.5 变量

            image.png

            image.png

            1.6 移除空格

            image.png

            image.png

            1.7 条件判断

            image.png

            image.png

            image.png

            image.png

            1.8 range遍历

            image.png

            image.png

            image.png

            image.png

            1.9 with

            image.png

            image.png

            image.png

            1.20 比较函数

            image.png

            1.21 预定义函数

            image.png

            image.png

            image.png

            案例演示:

            image.png

            image.png

            image.png

            

            1.22 原生模板嵌套

            image.png

            image.png

            image.png

            image.png

            

            1.23 block使用

            image.png

            image.png

            案例演示:

            image.png

            image.png

            image.png

            image.png

            1.24 修改默认标识符

            image.png

            image.png

            image.png

            1.25 转义js代码,防止xss攻击

            image.png

            image.png

            

        


            

            

            

            

             

            

            

            

            





            

            


【原创】 第十八章、数据操作
09 04 2022

第十八章、数据操作

        一、golang操作mysql

            1.1 安装第三方库

            进入到项目的src目录下,在终端执行:go get github.com/go-sql-driver/mysql

            image.png

            image.png

            1.2 连接mysql    sql.Open()

            image.png

            image.png

            image.png

            1.3 往mysql写入数据DB.Exec()

            image.png

            1.4 查询数据

            单行查询:db.QueryRow()

            image.png

            image.png

            多行查询:db.Query()

            image.png

            1.5 更新数据DB.Exec()

            image.png

            1.6 删除数据DB.Exec()

            image.png

            image.png


            1.7 mysql预处理 func (db *DB) Prepare(query string) (*stmt,error)

            一、预处理查询

            image.png

            二、预处理添加、删除、编辑语句类似

            image.png

            1.8 mysql事务DB.Begin()    DB.Commit()    DB.Rollback()

            image.png

            image.png

            image.png

            image.png

            

            1.9 演示sql注入     注意:任何时候,都不应该在项目中拼接SQL语句!!!

            image.png

            image.png

            image.png

            image.png


        二、golang操作sqlx库

            2.1 sqlx库基本介绍

            sqlx是 Go 的软件包,它在出色的内置database/sql软件包的基础上提供了一组扩展。

            该库兼容sql原生包,同时又提供了更为强大的、优雅的查询、插入函数。

            该库提供四个处理类型,分别是:

            sqlx.DB – 类似原生的 sql.DB;sqlx.Tx – 类似原生的 sql.Tx;sqlx.Stmt – 类似原生的 sql.Stmt, 准备 SQL 语句操作;sqlx.NamedStmt – 对特定参数命名并绑定生成 SQL 语句操作。

            提供两个游标类型,分别是:

            sqlx.Rows – 类似原生的 sql.Rows, 从 Queryx 返回;sqlx.Row – 类似原生的 sql.Row, 从 QueryRowx 返回。

            2.2 安装第三方库

            进入到项目的src目录下,在终端执

            image.png

            image.png

            2.3 链接数据库   sqlx.Connect()

            image.png

            image.png

            image.png

            2.4 单行查询Db.Get()

            image.png

            image.png

            2.5 多行查询Db.Get()

            image.png

            image.png

            2.6 Db.NameEcex()方法用来绑定SQL语句与结构体或map中的同名字段

            image.png

            image.png

            2.7 注意事项

            image.png

            

            

            

            

            



            


            

            


            

            


【原创】 第十七章、网络编程
22 03 2022

第十七章、网络编程

        一、网络编程基本介绍

            golang的主要设计目标之一就是面向大规模后端服务程序,网络通信是服务端程序必不可少的。

            1.1、网络编程两种方式:

            a、TCP socket编程,是网络编程的主流,之所以叫TCP socket编程,是因为底层基于TCP/IP协议的,比如:QQ

            b、B/S结构的HTTP编程,我们使用浏览器去访问服务器时,使用的就是http协议,而http底层依旧是用TCP socket实现的,比如:京东商城

        二、TCP/IP协议

            TCP/IP(Transmission Control Protocol/Internet Protocol)的简写,中文名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议,Internet国际互联网络的基础,简单的说,就是由网络层的IP协议和传输层的TCP协议组成

            2.1、OSI与TCP/IP参考模型

            image.png

            2.2、网线、网卡、无线网卡

            image.png

            2.3、聊天工具案例

            image.png

            2.4、IP地址

            image.png

            2.5、端口介绍

            image.png

            image.png

            image.png

            image.png

             使用Telnet链接IP和端口:

             第一步、win10搜索控制面板

             第二步、点击启用或关闭windows功能

             image.png

             第三步、安装Telnet

             image.png

             第四步、使用telnet IP 端口号   ; ctrl + ] 退出,quit退出...

             image.png


            2.6、TCP Socket编程的客户端和服务器端

            image.png


            2.7、TCP Socket编程入门案例

            要求:

            image.png

            分析:

            image.png

            服务端:

            image.png

            服务端代码:

            image.png

            image.png

            客户端代码:

            image.png

            改进:

            image.png


        三、Redis基本介绍

            3.1、需求分析

            image.png

            3.2、技术储备-redis 

            3.2.1、redis 基本介绍

            image.png

            3.2.2、redis安装和基本使用

            image.png

            操作原理图:

            image.png

            链接redis:

            image.png

            

            3.2.3、redis操作指令一览

            网址:http://redisdoc.com/

            3.2.4、redis的基本使用

            image.png

            3.3、Redis的CURD

            3.3.1、Redis的五大数据类型

            String(字符串)、Hash(哈希)、Lish(链表)、集合(Set)、有序集合(Zset)


            String基本介绍:

            a、String是redis最基本的类型,一个key对应一个value

            b、String类型是二进制安全的,除普通字符串外,也可以存放图片等数据;单个value最大值512M

            image.png

            c、set操作,set[如果key存在就相当于修改,如果不存在相当于添加];set key value;

            d、get操作,直接 get key键

            e、del操作,直接del key键

            image.png

            f、set设置过期时间, setex  key  过期时间 value

            image.png

            g、mset同时设置一个或多个 key-value对,如果给定的key已经存在,那么mset会用新值覆盖原来的旧值,格式:mset key1 value1 key2 value2,可以使用mget 获取全部值   也可以单独使用get 指定的键

            image.png


            Hash基本介绍(hash类似golang里面的map):

            a、Redis hash是一个键值对集合

            b、Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象

            c、设置指令格式: hset key field value    

            d、获取指令格式: hget key field 

            image.png

            e、获取所有: hgetall key

            image.png

            f、一次性设置所有:hmset key field value field value ...

            image.png

            g、一次性获取所有:hmget key field field ...

            image.png

            h、删除指定字段:hdel key field

            image.png

            i、hlen统计一个hash有几个元素

            image.png

            j、查看hash表key中,是否存在给定的field字段,指令格式:hexists key field

            image.png


            List(列表)基本介绍:

            列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

            List本质十个链表,List的元素是有序的,元素的值可以重复。

            List数据结构分析:

            image.png

            a、设置一个链表,从左边插入:lpush key value value value ...    依次放入aaa  bbb  ccc

            image.png

            b、获取链表内容,从左边“取出”(只是取出,链表中还存在这个数据):lrange key start stop ,这里的start代表开始,stop代表结束,当stop为-1的时候表示取到最后一个值,lrange key 0 -1,表示全部取出;依次取出 ccc  bbb  aaa  

            image.png

            image.png

            c、设置一个链表,从右边插入:rpush key value value value ...    依次放入ddd  eee

            image.png

            此刻再从左边取出, 看看数据结构:

            image.png

            d、从链表左边“弹出”(从链表中弹出移走数据):lpop key

            image.png

            e、从链表右边“弹出”(从链表中弹出移走数据):rpop key

            image.png

            f、删除整个链表:del key

            image.png

            注意事项:

            a、lindex  :按照索引下标获得元素(从左到右,编号从0开始)

            b、LLEN key :返回列表key的长度,如果key不存在,则key被解释为一个空列表,返回0

            c、List数据,可以从左 或者从右插入添加

            d、如果值全移除,对应的键也就消失了


            Set(集合)基本介绍:

            Redis的Set是string类型的无序集合,底层是Hash Table数据结构,Set也是存放很多字符串元素,字符串元素是无序的,而且元素的值不能重复

            a、添加数据到集合中:sadd key member member member ...   (member:成员)

            image.png

            b、从集合中取出所有数据:smembers key

            image.png

            c、判断值是否是成员:sismember  key  member 

            image.png

            d、删除集合中指定的成员:srem key member

            image.png

            注意事项:

            a、元素的值不能重复

            image.png


            3.3、Golang操作Redis

            3.3.1、安装第三方开源redis库

            image.png

            golang下载第三方扩展库:

            https://github.com/gomodule/redigo

            安装:进入到gopath目录下,在终端执行:go get github.com/gomodule/redigo/redis

            image.png

            3.3.2、String类型数据操作

            image.png

            3.3.3、Hash类型数据操作

            image.png


            image.png

            image.png


            3.3.4、Redis连接池基本介绍

            a、事先初始化一定数量的链接,放入到连接池

            b、当Go需要操作Redis的时候,直接从Redis连接池取出链接即可

            c、可以节省零时获取Redis链接的时间,从而提高效率

            d、示意图

            image.png

            核心代码:

            image.png

            连接池使用案例:

            image.png

            image.png

            

        四、用户即时通讯系统

            4.1、需求分析

            image.png

            4.2、功能一,显示客户端菜单

            image.png

            4.3、功能二,完成用户登录

            image.png

            

          image.png

            4.4、功能三,完成客户端可以发送消息本身,服务端可以正常接收到消息,并根据客户端发送的消息判断用户的合法性,并返回相应的LoginResMes

            image.png

            编译:去到项目的根目录执行,go build -o xxx.exe  从src下的目录开始直到文件所在的包

            image.png

            服务端代码改进以后的框架结构图:

            image.png

            客户端代码改进以后的框架结构图:

            image.png

            4.5、功能四,在redis手动添加测试用户,并画图+说明

            image.png

            image.png

            输入的用户名在redis中存在则登录,否则退出系统并给出相应的提示(账号密码错误或者用户不存在)

            




            

            



            



            

            



            

            



            

            







            

            


【原创】 第十六章、反射
18 03 2022

第十六章、反射

        一、基本介绍

            1.1、反射的基本介绍

            image.png

            image.png

            反射使用到的包

            image.png            


            1.2、反射的概念

            image.png

            image.png

            示意图:

            image.png

            image.png


            1.3、先看一个问题,反射的应用场景

            场景一

            image.png

            场景二

            image.png

            1.4、反射快速入门案例

            image.png

            image.png

            image.png

            image.png

            1.4、反射使用注意事项和细节

            image.png

            image.png

            image.png

            注意事项1:获取变量的类别,返回的是一个常量

            image.png

            image.png

            1.5、反射遍历结构体字段,调用结构体方法

            最佳实践1:

              image.png

            案例演示:

            image.png

            image.png

            image.png

            image.png

            最佳实践2

            image.png

            代码:

            image.png

            image.png  

            image.png          




【原创】 第十五章、goroutine和channel
12 03 2022

第十五章、goroutine和channel

        一、基本介绍

            1.1、什么是并行?

            在同一“时刻”,多件事情一起做;多线程程序在多核上运行,就是并行。特点:多个任务作用在多核CPU上,从微观的角度看,在同一时间点上,有多个任务在同时执行

            1.2、什么是并发?

            多线程程序在单核上运行,就是并发。特点:多个任务作用在一个CPU上;从微观的角度看,在一个时间点上只有一个任务在执行

            1.3、什么是线程?

            线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流。

            1.4、什么是进程?

            进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位,一个进程中可以创建和销毁多个线程,同一个进程中的多个线程可以并发执行,一个程序至少有一个进程,一个进程至少有一个线程。

            可以这么理解进程和线程,启动迅雷软件是一个进程,然后下载很多个电影资源就是多个线程;(程序加载到内存,运行起来就是进程)

            image.png


            1.5、什么是go协程?

            Go主线程(有程序员直接称之为线程/也可以理解成进程),一个Go线程上可以起多个协程,Go 协程可以看作是轻量级线程。与线程相比,创建一个 Go 协程的成本很小。因此在 Go 应用中,常常会看到有数以千计的 Go 协程并发地运行。

            “没有哪个程序是没有进程的”,Go协程的特点:

            1. 有独立的栈空间

            2. 共享程序堆空间

            3. 调度由用户控制

            4. 协程是轻量级的线程


        二、快速入门

            2.1、案例演示

            image.png

            image.png

            2.2、快速入门总结

            a、主线程是一个物理线程,直接作用在CPU上,是重量级的,非常耗费CPU资源

            b、协程是从主线程开启的,是轻量级的线程,是逻辑态的,对资源消耗相对较小

            c、golang的协程是重要的特点,可以轻松开启上万个协程,其他语言的并发机制一般是基于线程的;开启过多的线程,资源耗费大,这里就凸显golang在并发上的优势了

        三、Goroutine调度模型

            3.1、MPG基本模式介绍

            M(Machine):操作系统的主线程

            P(Processor):协程执行需要的资源(上下文context)

            G(Gorountine):协程,有自己的栈。包含指令指针(instruction pointer)和其它信息(正在等待的channel等等),用于调度。一个P下面可以有多个G

            image.png

            image.png

            3.2、MPG模式运行状态1

            image.png

            3.3、MPG模式运行状态2

            image.png

            3.4、设置golang运行的CPU数

            image.png


        四、channel(管道)

            4.1、完成下面需求

            image.png

            image.png

            执行ceshi.exe 结果如下:

            image.png

            

            存在问题的代码:

            image.png

            4.2、解决办法

            方法一:全局变量加锁同步改进程序

            image.png

            原理:

            image.png

            使用锁会用到的包:

            image.png

            代码改进:

            image.png

            image.png

            image.pngimage.pngimage.png

            方法二:channel通讯机制改进

            4.3、管道基本介绍

            image.png

            image.png

            4.3.1、管道示意:

            image.png

            image.png

            image.png

            4.3.2、管道基本使用

            声明/定义channel:

            var 变量名  chan 数据类型   !!!


            var perChan chan *Person

            var intChan  chan int

            var mapChan chan map[int]string    (用于存放map[int]string类型数据)

            说明:

            1.channel是引用类型

            2.channel必须初始化才能写入数据,即make后才能使用

            3.channel是有类型的,intChan 只能写入int类型数据

            

            演示管道的使用:

            image.png

            image.png

            4.3.3、channel使用注意事项

            a、channel中只能存放指定的数据类型

            b、channel中数据放满了就不能再往里面存放数据了

            c、如果从channel中取出数据以后就可以继续存放

            d、在没有使用协程的情况下,如果channel数据取完了,再取,就会报dead lock


            4.3.4、读写channel案例演示

            image.png

            image.png

            4.3.5、channel的遍历和关闭

            image.png

            image.png

            4.3.5、goroutine和channel协同工作

            需求:完成goroutine和channel协同工作

            1.开启一个writeData协程,向intChan中写入50个数据

            2.开启一个readData协程,从intChan中读取writeData写入的数据.

            注意:writeData和writeData操作的是同一个管道

            3.主线程需要等writeData和writeData协程完成工作才能退出

            image.png

            image.png

            image.png

            4.3.6、goroutine和channel  --  阻塞

            管道容量10,只向管道里面写入数据,写入50个数据,而没有读取,就会出现阻塞而deadlock!

            图1

            image.png

            图2

            image.png

            图3

            image.png

            图4

            image.png

            

            goroutine和channel应用3

            image.png

            思路分析:

            image.png

            代码:

            图一

            image.png

            图二

            image.png

            图三

            image.png


            4.4、channel使用细节和注意事项

            a、channel可以声明为只读,或者只写性质

            image.png

            image.png

            b、使用select可以解决从管道读取数据的阻塞问题

            基本语法:

            image.png

            image.png

            c、goroutine中使用recover, 解决协程中出现panic,导致程序崩溃的问题

            错误代码:

            image.png

            defer + recover

            image.png

            image.png












            


【原创】 第十四章、单元测试
11 03 2022

第十四章、单元测试

        一、基本介绍

            1.1、在工作中,我们经常会遇到这样的情况,就是去确认一个函数或者一个模块的结果是否正确,如:

            image.png

            1.2、传统方式测试

            在main函数中,调用addUpper函数,看看实际输出的结果是否和预期的结果一致,如果一致则说明函数正确,不一致则函数有问题

            案例:

            image.png

            分析:

            1、测试不方便, 我们要在main函数中去调用,这样就需要去修改main函数,如果项目正在运行,就有可能去停掉项目

            2、不利于管理,当我们测试多个函数或者多个模块时,都需要写在main函数,不利于我们管理和清晰思路

            3、引出单元测试,testing测试框架,可以很好的解决问题

            1.3、单元测试基本介绍

            image.png

            1.3.1、单元测试基本入门

            image.png

            image.png

            

            image.png

            1.3.2、单元测试基本原理


            image.png

            1.3.3、单元测试总结

            a、测试用例文件名必须以_test.go结尾,如:cal_test.go,cal不是固定的

            image.png

            b、测试用例函数必须以Test开头,一般来说就是Test+被测试的函数名,比如TestAddUpper(),Test后面的第一个字母必须大写

            c、TestAddUpper(t *testing.T)的参数类型必须是testing.T

            d、一个测试文件中可以有多个测试用例函数,比如TestAddUpper()   TestGetSub()等等   

            e、运行测试用例指令:

                命令行去到测试用例文件所在文件夹,执行go test,【如果运行正常,无日志;运行错误,输出日志】

                命令行去到测试用例文件所在文件夹,执行go test -v,【如果运行正常、错误,都会输出日志】

            f、当出现错误时,可以使用来格式化t.Fatalf() 输出信息,并退出程序

            g、t.Logf()方法可以输出相应日志        

            h、测试用例函数并没有放在main()函数中,也执行了,这就是测试用例函数的方便之处

            i、PASS表示测试用例运行成功,FAIL表示测试用例运行失败   

            j、测试单个文件,一定要带上被测试的源文件,go test -v cal_test.go cal.go

            image.png

            k、测试单个方法,go test -v  -test.run TestAddUpper

            image.png 

            1.3.4、单元测试综合案例_练习

            image.png

            代码:

            image.png

            image.png

            image.png

            image.png

            


【原创】 第十三章、文件的基本介绍
05 03 2022

第十三章、文件操作

        一、基本介绍

            1.1 概念

            文件在程序中是以流的形式来操作的

              image.png

            1.2 File文件位置

            在开发中操作文件,经常会用到os.File结构体

            image.png

            1.3 File文件读取操作

            a、打开文件

              b、关闭文件

            image.png

            c、读取文件并显示在终端(带缓冲区的方式)

            image.png

            d、直接读取文件内容

            image.png

            image.png

            1.4 File文件写操作

            a、使用带缓存的方式往文件中写入内容

            image.png

            image.png

            b、读取一个文件的内容,写入到另一个文件

            image.png

            1.5 判断文件或文件夹是否存在

            image.png

            1.6 将一个目录下的文件拷贝到另一个目录

            image.png

            1.7 os.Args存储所有的命令行参数

            image.png

            image.png

            1.8 使用flag包来解析命令行参数的用法

            image.png

            1.9 json基本介绍

            image.png

            1.9.1、json应用场景介绍

            image.png

            1.9.2、json工具站点:https://www.json.cn/

            1.9.3、json的序列化

            image.png

            1.9.4、json的序列化案例演示

            image.png

            image.png

            

            image.png

            image.png

            1.9.5、json的tag标签的使用

            image.png

            1.9.6、json反序列化

            image.png

            案例演示

            image.png

            image.png

            说明:

            1. 在反序列化一个json字符串时,要确保反序列化后的数据类型和原来反序列化前的数据类型一致,比如结构体,字段数量和名字保持一致,不能多不能烧

            2. 如果json字符串是通过程序获取到的,则不需要再 " 转义处理了。

            image.png



【原创】 第十二章、面向“对象”编程
28 12 2021

第十二章、面向“对象”编程

        一、结构体

            1.1 概念

            一个程序就是一个世界,有很多对象(变量)

            1.2 golang语言面向对象编程说明

            a、golang也支持面向对象编程(oop),但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言,所以我们说golang支持面向对象编程特性是比较准确的。

            b、golang没有类(class),go语言的结构体(struct)和其他编程语言的类(class)有同等的地位,可以理解golang 基于struct来实现OOP特性的。

            c、golang面向对象编程非常简介,去掉了传统语言的继承、方法重载、构造函数和析构函数,隐藏的this指针等等

            d、golang仍然有面向对象编程的继承、封装和多态特性,只是实现的方式和其他OOP语言不一样,比如继承:golang没有extends关键字,是通过匿名字段来实现的

            e、golang面向对象(OOP)很优雅,OOP本身就是语言类型系统的一部分,通过接口(interface)关联,耦合性低,也非常灵活。

            1.3 结构体

            

image.png


            对上图说明:

            a、将一类事务的特性提取出来(比如猫),形成一个新的数据类型,就是一个结构体

            b、通过这个结构体,我们可以创建多个变量(实例/对象)

            c、事务可以是人类、商品、工具类...

            1.3 结构体和结构体变量的区别联系

            a、结构体是自定义的数据类型,代表一类事物

            b、结构体变量是具体的、实际的、代表一个具体变量

            1.4 结构体在内存的布局

            声明未赋值:

            image.png

            结构体赋值以后:

            image.png

            1.5 如何声明结构体

            1.5.1、声明

            image.png

            1.5.2、字段/属性

            a、从概念或者叫法上看:结构体字段=属性=field

            b、字段是结构体的一个组成部分,一般是基本数据类型、数组、也可以是引用数据类型,比如前面我们定义的猫猫结构体,Name string就是属性

            1.5.3、字段/属性注意事项(结构体是值类型!!!)

            image.png

            注意事项3:

            image.png

            注意事项4:不同结构体字段是独立的,互不影响

            image.png

            image.png

            画出上面代码的内存示意图:

            第一步、值拷贝

            image.png

            第二步、修改值

            image.png

            1.5.4、创建结构体变量和访问结构体字段

            image.png

            image.png

            image.png

            image.png

            image.png

            image.png

            image.png

            1.5.5、struct类型的内存分配机制

            image.png

            image.png

            image.png

            1.5.6、结构体的注意事项和使用细节

            a、结构体的所有字段在内存中 是连续的

             image.png

            b、结构体是用户单独定义的类型,和其他类型转换时需要有完全相同的字段(名字、个数和类型)

            image.png

            c、结构体进行type重新定义(相当于取别名),golang认为是新的数据类型,但是互相间可以强转

            image.png

            d、struct的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景就是序列化和烦序列化

            image.png

            image.png

            案例演示:

            image.png

            image.png


        二、方法

            2.1 基本介绍

            image.png

            2.2 方法的声明和调用

            image.png

            image.png

            上面代码说明:

            a、func (a A) test(){}    表示A结构体有一个方法,方法名test

            b、(a A) 体现test方法和A类型绑定

            案例演示:

            image.png

            对上面代码总结:

            a、test()方法和类型Person5绑定

            b、test()方法只能通过Person5类型的变量来调用,而不能直接调用,也不能使用其他类型变量来调用

            c、func(p Person5)test(){},  p表示哪个Person5变量调用,这个p就是它的副本,这点和函数的传参非常相似

            d、p这个名字,由程序员指定,不固定

            练习案例:

            1.

            image.png

            image.png

            2.

            image.png

            image.png

            2.3 方法的调用和传参机制

            说明:方法的调用、传参机制和函数基本一样,不一样的地方是方法调用时,会将调用方法的变量,当做实参也传递给方法

            image.png

            image.png

            image.png

            2.4 方法注意事项和细节

            a、结构体类型是值类型,在方法调用中,遵守值类型传递机制,是值拷贝传递方式

            b、如果程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理,通常也多用指针方式,程序运行效率更高

            image.png

            内存说明:

            image.png

            c、golang中的方法作用在指定类型上,(即:和指定的数据类型绑定),因此,自定义类型都可以有方法,而不仅仅是struct,比如int、float64等等都可以

            image.png

            d、方法的访问范围控制规则,和函数一样。方法名首字母小写,只能在本包访问,方法名首字母大写,可以在本包和其他包函数访问

            e、如果一个类型实现了String()这个方法,那么fmt.Println默认会调用这个类型的String()进行输出,一般可以用在日志记录

            image.png

            2.5 方法和函数的区别

            a、调用方式不一样

            函数的调用方式:函数名(实参列表)

            方法的调用方式:变量.方法名(实参列表)

            b、对于普通函数,接收者为值类型时,不能将指针类型的数据传递,反之亦然

            image.png

            c、对于方法,接受者为值类型时,可以直接用指针类型的变量调用方法,反过来同样可以

            image.png

            image.png

            image.png

        三、面向对象编程应用实例

            3.1 步骤

            image.png

            3.2 创建结构体变量时指定字段值

            image.png

            3.3 工厂模式

            image.png

            image.png

            image.png

            工厂模式解决结构体中结构体名字首字母小写问题::

            image.png

            image.png

            如果结构体student的age字段首字母也是小写,在其他包不可以直接访问,我们可以提供一个方法

            image.png

            image.png

            3.4 面向对象编程思想-抽象

            简介:

            image.png

            案例演示:

            image.png

            image.png

            image.png

            3.5 面向对象编程的三大特性

            3.5.1 基本介绍

            golang仍然有面向对象编程的继承、封装、多态的特性,只是实现的方式和其他的OOP语言不一样

            3.5.2 封装:封装就是把抽象出来的字段和对字段的操作封装在一起,数据被保护在内部,程序的其他包只有通过被授权的操作(方法),才能对字段进行操作

           image.png 

            封装的实现步骤:

            1、将结构体、字段的首字母小写(不能导出,其他包不能使用,类似private)

            2、给结构体所在的包提供一个工厂模式的函数,函数名首字母大写,类似一个构造函数

            3、提供一个首字母大写的Set方法

            image.png

            4、提供一个首字母大写的Get方法

            image.png

            特别说明:在golang开发中并没有特别强调封装,这点并不像java、PHP,golang本身对面向对象的特性做了简化的

            案例:

            image.png

            image.png


            3.5.3 继承:当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出这些结构体,在该结构体中定义相同的属性和方法,其他的结构体不需要重新定义这些相同的属性和方法,只需要嵌入一个(基础结构体的)匿名结构体就可以了;也就是说,一个结构体嵌套了另一个匿名结构体,那么这个结构体就可以直接访问匿名结构体的属性和方法,从而实现继承特性

            画图说明继承的特性:

            image.png

            嵌套匿名结构体的基本语法:

            image.png

            案例演示:

            image.png

            image.png

            继承给编程带来的便利:

            a、代码的复用性提高了

            b、代码的扩展性和维护性提高了

            继承深入讨论:

            a、结构体可以使用嵌套匿名结构体的所有字段和方法,即:首字母大写、小写的字段 方法都可以使用, 注意::但是跨包不能访问小写字段和方法

            b、匿名结构体字段访问可以简化

            image.png

            上图代码说明:

            image.png

            c、当结构体和匿名结构体有相同的字段或方法时,编译器采用“就近原则”访问,如果希望访问匿名结构体的子弹和方法,可以通过匿名结构体来区分

            d、当结构体嵌入多个匿名结构体...

            image.png


            e、如果一个struct嵌套了一个"有名结构体",这种模式就是“组合”,如果是组合关系,那么在访问组合的结构体方法或字段时,必须带上结构体的名字 

            image.png

            f、嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值


            image.png

            image.png

            指针方式:

            image.png

            image.png

            g、结构体中匿名字段使用

            image.png


        四、接口

            4.1.1 golang接口简介

            interface类型可以定义一组方法,但是这些方法不需要实现,并且interface不能包含任何变量,到某个自定义类型(比如下面列子的结构体Phone)要使用的时候,再根据具体情况把这些方法写出来(实现)。

            image.png

            4.1.2 基本语法

            image.png

            image.png

            4.1.3 为什么会有接口

            image.png

            4.1.4 入门案例演示

             image.png

            image.png

            image.png

            4.1.5 接口注意事项和细节说明

            a、接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)

            image.png

            b、接口中所有的方法都没有方法体,即:都是没有实现的方法

            c、在golang中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口

            d、只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型

            image.png

            image.png

            e、一个自定义类型可以实现多个接口

            image.png

            image.png

            f、golang接口中不能有任何变量,编译不过,会报错

            g、一个接口(比如A接口),“可以继承多个”别的接口(比如B、C接口),这时如果要实现A接口,必须将B、C接口的方法全部实现

            image.png

            image.png

            h、interface类型默认是一个指针(引用类型),如果没有对interface初始化就使用,那么会输出nil

            i、空interface{}没有任何方法,所以,所有类型都实现了空接口(换句话说就是,我们可以把任何数据类型的变量赋值给空接口)

            image.png

            image.png

            4.1.6 接口编程实践

            image.png

            image.png

            4.1.7 实现接口 vs 继承

            image.png

            案例演示:

            image.png

            image.png

            说明:

            a、当结构体B继承了结构体A,那么结构体B就自动的继承了结构体A的字段和方法,可以直接使用

            b、当B结构体需要扩展功能,同时不希望破坏继承关系,则可以去实现接口,因此我们认为:实现接口是对继承的补充!!!

            4.1.8 接口 和 继承的区别

            image.png


        五、面向对象编程-多态

            5.1.1 基本介绍

            变量(实例)具有多种形态,在go语言中,多态特征是通过接口来实现的,可以按照统一的接口来调用不同的实现,这时接口变量就呈现不同的形态。

            5.1.2 接口体现多态的两种形式

            image.png

            案例演示:

            image.png

            image.png

            5.1.3 类型断言基本介绍

            类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言

            image.png

            如何在断言时,带上监测机制,如果成功就ok,否则也不要报panic

            image.png

            5.1.4 类型断言实践

            第一题、usb接口案例

            image.png

            image.png

            第二题、写一个函数, 循环判断传入参数的类型

            image.png

            image.png


【原创】 第十一章、go内置函数
08 12 2021

第十一章、go内置函数以及错误处理

        11.1 go内置函数

                1、内置函数简介

                golang设计者为了编程方便,提供了一些函数,这些函数可以直接使用,我们称之为内置函数(也叫内建函数),https://studygolang.com/pkgdoc -> builtin包

                2、一些常用内置函数

                len()函数

                image.png

                new()函数:用来分配内存,主要用来分配值类型,比如:int、float、struct...  返回的是指针 

                image.png

                内存分配示意图:

                image.png

                image.png

                make()函数:用来分配内存,主要是用来分配引用类型,比如chan、map、slice


        11.2 golang错误处理

                11.2.1 看一段代码

                image.png

                说明:

                a、在默认情况下,当发生错误(panic)后,程序就会退出(崩溃)

                b、如果我们希望:在发生错误后可以捕捉到错误,并进行处理保证程序可以继续执行,可以在捕捉到错误以后,给管理员发送邮件或者短信...

                c、这里引出错误处理机制

                

                11.2.2 golang错误处理基本说明

                image.png

                案例:

                image.png

                错误处理的好处:进行错误处理后,程序不会轻易挂掉,如果加入预警代码,就可以让程序更加的健壮


        11.3 自定义错误处理

                11.3.1 在go中也支持自定义错误,使用errors.New和panic内置函数

                第一步、errors.New("错误说明"),会返回一个error类型的值表示一个错误

                第二步、panic内置函数,接收一个interface{}类型的值(也就是任何值)作为参数,可以接收error类型的变量,输出错误信息,并退出程序

                image.png

                

                




                

【原创】 第十章、go中常用函数
03 12 2021

第十章、go中常用函数

        10.1 字符串中常用系统函数

                1、统计字符串长度(字节),len(str)

                image.png

                2、统计字

                字符串遍历,同时处理有中文的问题  r:=[]rune(str)

                image.png

                3、字符串转整数  n,err := strconv.Atoi()

                image.png

                4、整数转字符串  str := strconv.Itoa(632)

                image.png

                5、字符串转[]byte    var bytes = []byte("abds")

                image.png

                6、[]byte转字符串   str := string([]byte{97,98,99})

                image.png

                7、十进制转2,8,16进制   str = strconv.FormatInt(i int64, base int) string

                image.png

                8、查找子串是否在指定的字符串:

                image.png

                image.png

                9、统计一个字符串有几个指定的子串   strings.Count("cheseese","e")

                image.png

                10、不区分大小写的字符串比较(==是区分字母大小写的)    strings.EqualFold("ab","Ab")

                image.png

                image.png

                11、返回子串在字符串第一次出现的index值(位置),如果没有返回-1   strings.Index("FDJ_abc","abc")

                image.png

                12、返回子串在字符串最后出现的位置,如果没有则返回-1  strings.LastIndex("go golanmg","go")

                image.png

                13、将指定的子串替换成另一个子串strings.Replace("go go go hello","go","go语言",n),n可以指定你希望替换几个,如果n<0 表示全部替换

                image.png

                14、按照指定的某个字符 为分割标识符,将一个字符串拆分成字符串数组strings.Split("hello,world,ok",",")

                image.png

                15、将字符串的字母进行大小写转换strings.ToLower("Go") //strings.ToUpper("Go") //GO

                image.png

                16、将字符串左右两边的空格去掉 strings.TrimSpace(" ds a long ntr ")

                image.png

                17、将字符串左右两边指定的字符去掉strings.Trim("! hello !"," !")

                image.png

                18、将字符串左边指定的字符去掉strings.TrimLeft("!hello!","!")

                image.png

                20、判断字符串会否以指定的字符串开头strings.HasPrefix("ftp://192.168.3.1","ftp") //true

                image.png

                21、判断字符串会否以指定的字符串结尾strings.HasSuffix("qaq.jpg","jpg")

                image.png


        10.2 时间和日期相关函数

                10.2.1、简介:时间和日期相关函数,需要导入time包

                10.2.2、time.Time类型用于表示时间

                image.png

                10.2.3、获取其他的日期信息

                image.png

                10.2.4、格式化日期和时间

                a、使用Printf或者Sprintf

                image.png

                b、Format函数格式化

                说明:

                使用format函数,参数“2006/01/02 15:04:05”这个字符串是固定式,必须这样写,据网上流传是go语言设计者想设计一门新语言想法的最初时间;这个字符串的格式可以改变,但是数字数据不能改变

                image.png

                10.2.5、时间的常量

                image.png

                不能在时间单位后面去除一个数 ,只能用时间单位乘以一个数字来表示要表达的时间

                案例演示,配合sleep(休眠)做如下练习,func Sleep(d Duration) time.Sleep(100 * time.Millisecond) 表示100毫秒

                image.png

                10.2.6、获取当前unix时间戳和unixnano时间戳(作用是可以获取随机数字)

                image.png

                练习:

                image.png

                


                



                

【原创】 第九章、函数
29 11 2021

第九章、函数

        9.1 函数基本介绍

                函数是为完成某一功能的程序指令(语句)的集合,称为函数。在go中,函数分为自定义函数和系统函数。

        9.2 函数基本语法

                基本语法如下:   

                image.png

                案例:

                image.png

        9.3 go中的包

                9.3.1 包的基本概念

                go的每一个文件都是属于一个包的,也就是说go是以包的形式来管理文件和项目目录结构的

                9.3.2 包的引出

                在实际的开发中,我们往往需要在不同的文件中,去调用其他文件定义的函数,比如在main.go中去使用utils.go中的函数  

                9.3.3 包的原理

                包的本质:实际上就是创建不同的文件夹,来存放程序文件

                image.png

                

                image.png

                9.3.4 包的三大作用

                a、区分相同名字的函数、变量等标识符

                b、当程序文件较多时,可以很好的管理项目

                c、控制函数、变量等访问范围,即作用域

                9.3.5 打包基本语法

                package 包名

                9.3.6 引入一个包

                import "包的路径"

                9.3.7 包的快速入门,调用包中的函数

                案列:

                image.png


                image.png


                image.png

                9.3.8 包的注意事项和细节说明

                image.png


                image.png


                image.png

        9.4 函数的调用机制

                9.4.1 基本介绍

                image.png

                image.png

                9.4.2 golang中,函数调用机制的底层分析

                image.png

                1. 第一步,主函数n1赋值,主函数中去调用test()函数;在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身的处理让这个新的空间和其他栈的空间区分开来

                image.png

                2. 第二步,test()函数执行完毕,终端输出n1=11,编译器回收test()函数里面的变量;在每个函数对应的栈中,数据空间是独立的,不会混淆;当一个函数执行完毕,程序会销毁这个函数对应的栈空间

                image.png

                3. 第三步,main()函数也执行完毕,终端输出test()中的n1=11,main()函数的n1=10,编译器回收main()函数里面的n1变量

                image.png

                9.4.3 案例演示

                image.png

                9.4.4 函数中return 语句介绍

                image.png

        9.5 递归函数

                9.5.1 递归函数简介

                一个函数在函数体内又调用了本身,我们称为递归调用

                案例演示:

                image.png

                过程分析图:

                image.png

                递归调用的总结:

                image.png

                9.5.2 递归练习题

                练习1:请使用递归的方式,求出斐波拉契数    1,1,2,3,5,8,13,21...

                image.png

                练习2:习题如下

                image.png

        9.6 函数注意事项和细节讨论

                image.png

                image.png 

                image.png

                案例演示第6:

                image.png

                第一步、

                image.png

                第二步、

                image.png

                案例演示第6、第8:

                image.png

                案例演示第10:

                image.png

                案例11:

                image.png

                image.png

                案例演示第13:

                image.png

        9.7 init函数

                9.7.1 基本介绍

                每一个源文件都可以包含一个init函数,该函数会在main函数之前执行,被go运行框架调用,也就是说init函数会在main函数之前被调用

                9.7.2 案例演示

                image.png

                9.7.3 细节讨论

                a、如果一个文件同时包含init函数、main函数、全局变量定义,则执行的流程顺序是全局变量定义 -> init函数 -> main函数

                image.png

                a、init函数的主要作用,就是完成一些初始化工作

                案例如下:

                image.png

                image.png

                a、如果主函数main.go  和初始化函数init.go中都含有变量定义,执行的流程又是怎么样的呢?

                image.png

                image.png

        9.8 匿名函数

                9.8.1 基本介绍

                Go支持匿名函数,如果我们某个函数只希望使用一次,可以考虑使用匿名函数匿名函数也可以实现多次调用

                9.8.2 匿名函数使用方

                使用式1:

                在定义匿名函数时就直接调用这种方式匿名函数只能调用一次

                image.png

                使用式2:

                将匿名函数赋值给一个变量(函数变量),再通过该变量来调用匿名函数

                image.png

                9.8.3 全局匿名函数

                如果将匿名函数赋值给一个全局变量,那么这个匿名函数就是一个全局匿名函数

                image.png

                image.png

        9.9 闭包函数

                9.8.1 基本介绍

                闭包就是“一个函数”和“与其相关的引用环境”组合的“整体(实体)”

                9.8.2 案例演示1

                image.png

                对上面代码说明和总结:

                1、AddUpper()是一个函数,返回的数据类型是 func(int) int

                2、闭包的说明:返回的是一个函数, 返回的是这个匿名函数,但是和这个匿名函数引用到了函数外面的变量n,因此这个匿名函数就和n形成一个整体,构成闭包

                image.png

                3、可以这样理解:闭包是一个类,函数是操作,n是字段,函数和它使用到的n构成闭包

                4、当我们反复调用f函数时,因为n是初始化一次,因此每调用一次就进行累计

                5、我们要搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包

                案例演示2

                image.png    

                代码说明:返回的匿名函数和makeSuffix(suffix string)的suffix变量组成一个闭包,因为返回的函数引用到suffix这个变量            

                闭包的好处:闭包可以把匿名函数引用到的变量保存(引用)下来,进行下次调用回

        9.10 函数中的defer

                9.10.1 基本介绍

                在程序中,程序员经常需要创建资源,(比如:数据库链接、文件句柄、锁等~),为了再函数执行完毕后,及时的释放资源,go的设计者提供defer延时机制

                9.10.2 案例说明

                image.png

                9.10.3 defer细节说明

                a、当go执行到一个defer时,不会立即执行defer后的语句,而是将defer后的语句压入到一个栈中,然后继续执行函数下一个语句

                b、当函数执行完毕以后,再从defer栈中依次从栈顶取出语句执行,注意:(入栈先入后出机制)

                c、在defer将语句入栈时,也会将相关的值拷贝同时入栈!!! 

                image.png

                d、函数中,defer的最佳实践!!!!!!!!!!

                image.png

                image.png

        9.11 函数参数的传递方式

                9.11.1 基本介绍

                值类型默认就是值传递,而引用类型参数默认就是引用传递

                其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是值传递的是值的拷贝,而引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低

                9.11.2 值类型和引用类型

                值类型:基本数据类型int系列、float系列、bool、string、数组和结构体struct

                引用类型:指针、slice切片、map、管道chan、interface等都是引用类型

                image.png

                3)如果希望函数内的变量能改变函数外的变量,可以传入变量的地址,(&num),函数内以指针的方式操作变量

        9.12 变量作用域

                9.12.1 基本介绍

                a、函数内部声明/定义的变量叫局部变量,作用域仅限于函数内部 

                b、函数外部声明/定义的变量叫全局变量,作用域在整个包都有效,如果其首字母大写,在整个程序有效

                9.12.2 案例演示

                image.png

                注意:::

                image.png

                image.png



【原创】 第八章、Golang程序流程控制语句
24 11 2021

第八章、程序流程控制

        8.1、程序流程控制介绍

                图片.png

        8.2、顺序结构语句

                图片.png

        8.3、分支结构语句

                图片.png

                8.3.1 单分支结构

                基本语法如下:

                图片.png

                举例:

                图片.png

                注意事项:

                go 语句的if 后面必须是一个条件表达式,不能是赋值语句

                图片.png

                图片.png

                image.png

                8.3.2 双分支结构

                基本语法如下:

                图片.png

                举例:

                图片.png

                8.3.3 多分支结构

                基本语法如下:

                图片.png

                流程图:

                图片.png

                案例:

                图片.png

                图片.png

                注意事项:多分支流程图中 任何时候只会有一个分支会有输出结果,走到那一块就结束了

                图片.png

                8.3.4 多分支结构

                图片.png

                举例:

                image.png

        8.4、switch分支结构语句

                8.4.1 switch简介

                image.png

                image.png

                8.4.2 switch流程图

                image.png

                8.4.3 举例

                image.png

                8.4.4 注意事项:

                image.png

                注意:

                image.png

                image.png

                image.png

                image.png

                image.png

                image.png

                8.4.5 switch和if的比较

                image.png

        8.5、for循环控制语句

                8.5.1 for循环语句简介

                image.png

                8.5.2 for循环流程图

                image.png

                8.5.3 for循环使用细节

                image.png

                8.5.4 举例

                image.png

                image.png

                image.png

        8.6、go中没有while和do...while的实现

                image.png              

                8.6.1 for循环实现while效果

                image.png

                案例:

                image.png

                8.6.2 for循环实现do...while效果

                image.png

                image.png

                案例:

                image.png

        8.7、多重循环

                8.7.1 基本介绍

                image.png

                案例1:

                image.png

                案例2:

                image.png

                image.png

                代码如下:

                image.png

                image.png

        8.8、跳转控制语句break

                8.8.1 基本语法介绍

                image.png

                8.8.2 流程图

                image.png

                8.8.3 案例

                image.png

                8.8.4 break使用细节

                image.png

                image.png

                说明:

                break 默认跳出最近的一层for循环

                break 后面可以指定标签,跳出标签对应的for循环

        8.9、跳转控制语句continue

                8.9.1 基本语法介绍

                continue语句用于结束本次循环,继续执行下一次循环

                image.png

                8.9.2 continue流程图

                image.png

                8.9.3 案例

                image.png

        8.10、跳转控制语句goto

                8.10.1 基本介绍

                image.png

                8.10.2 案例

                image.png

        8.11、跳转控制语句return

                8.11.1 基本介绍

                return使用在方法或者函数中,表示跳出所在的方法或函数。

                说明:

                1、 如果return是在普通的函数中,则表示跳出该函数,既不再执行函数中return后面的代码,也可以理解成终止函数。

                2、如果return是在main函数,表示终止main函数,也就是说终止程序。

                image.png

【原创】 第七章、Golang运算符
23 11 2021

第七章、Golang运算符

        1、Go语言运算符

            1.1 基本介绍

                介绍:运算符是一种特殊的符号,用于数值的运算、赋值、比较等.

                算术运算符:                   + - * / 取模

                赋值运算符:                   = += -= *= /= 

                比较运算符/关系运算:    == != >=  <= > <

                逻辑运算符:                   与 或 非

                位运算符:                      位与   位或  位异或  位左移   位右移

                其他运算符:                   取址运算符 &    取值运算符 *

            1.2 算术运算符

                介绍:对数值类型的变量进行运算,如加减乘除

                图片.png

                演示/的使用:

                图片.png

                演示%的使用:

                图片.png

            1.2.1 算术运算符使用注意事项

    a、对于除号 "/",它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。  例如:  x := 19/5 ,结果是3

                b、当对一个数取模时,可以等价 a%b = a-a/b*b  , 这样我们可以看到 取模的一个本质运算。

                c、对Golang 的自增自减只能当做一个独立语言使用时,不能这样使用 b := a++  或者 b := a--

                d、Golang的++和--只能写在变量的后面,不能写在变量的前面, 没有 --a   ++a 这样的写法

                图片.png

                e、Golang设计者去掉了C/java中容易混淆的自增自减的写法,让Golang 更加简介 统一

            1.2.2 算术运算符练习

                图片.png

            1.3 关系运算符(比较运算符)

                介绍:关系运算符的结果都是bool型,要么是true 要么是false

                          关系表达式经常用在if结构的条件中或循环结构的条件中

                图片.png

            1.3.1 关系运算符使用细节

                a、关系运算符的结果都是bool型,要么是true 要么是false

                b、关系运算符组成的表达式,我们称为关系表达式,如 a > b

                c、比较运算符"==" 不能写成 "="

            1.4 逻辑运算符

                介绍:用于连接多个条件(一般来讲就是关系表达式),最终的结果也是bool值

                图片.png

                练习:

                图片.png

            1.4.1 逻辑运算注意事项和细节说明

                  &&也叫短路与,如果第一个条件为false,则第二个条件不会判断,结果为false

                  ||也叫短路或,如果第一个条件为true,则第二个条件也不会判断,结果为true 

            1.5 赋值运算符

            1.5.1 赋值运算符介绍

                图片.png

                图片.png

            1.5.2 例子

                图片.png

            1.5.3 赋值运算符特点

                a、运算顺序从右到左

                b、赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值等


            1.6 运算符优先级

                图片.png


            1.6.1 位运算符

                图片.png

                golang中的位运算符:

                图片.png

                举例:

                图片.png

                计算过程:

                图片.png

                移位注意事项:

                图片.png



            1.6.2 位运算符

                图片.png


                举例实现三元运算符效果:

                图片.png


            1.7 键盘输入语句

            1.7.1 介绍:在开发中,需要接收到用户输入的数据,就需要使用键盘输入语句来获取

            1.7.2 步骤

                a、导入fmt包

                b、调用fmt包的函数,fmt.Scanln()  或者fmt.Scanf()

            1.7.3 需求:从控制台接收用户信息,年龄、姓名、薪水、是否通过考核

                方式一、fmt.Scanln()

                图片.png

              方式二、fmt.Scanf()

                图片.png

            1.8 计算机基础进制转换

                1.8.1 基数简介

                进制其实就是基数,大于或等于基数时,向高位进1。10进制基数就是10,二进制基数就是2,八进制(8)、十六进制(16)。

                图片.png

                1.8.2 原码、反码、补码

                图片.png



【原创】 第六章、Golang标识符
20 10 2021

第六章、Golang标识符

        1、标识符的命名规范

            1.1 基本介绍

                a、对Golang对各种变量、方法、函数等命名时使用的字符序列称为标识符

                b、凡是自己可以起名字的地方都叫标识符,比如:var num int    var name string都是标识符

            1.2 标识符的命名规则

                a、由26个大小写英文字母、0-9、_组成

                b、数字不能开头

                c、golang中严格区分大小写

                d、标识符不能包含空格

                e、下划线“_”本身在go中是一个特殊的标识符,称为空标识符,可以代表其他任何的标识符,但是它对应的值会被忽略(比如忽略某个返回值),所以仅能被作为占位符使用,不能作为标识符使用

                f、中文在go中定义变量的时候不会报错,编译也通过,但是定义go变量的时候不推荐使用中文

                图片.png

                f、不能以系统保留的关键字作为标识符,比如 if 、break等等...

                图片.png

            1.3 标识符案列

                  图片.png 

            1.4 标识符命名注意事项

                a、包名:保持package的名字尽量和目录一致,尽量采用有意义的包名;简短有意义,不要和标准库冲突

                图片.png

                b、变量名、函数名、常量名:采用驼峰法,比如:var  studentName string = "暗夜猎手薇恩";  var goodsPrice float64 = 15.5

                c、如果变量名、函数名、常量名首字母大写,则可以被其他的包访问,如果首字母小写,则只能在本包中使用(注:可以理解成,首字母大写是公有的,首字母小写是私有的,其他编程语言的关键字public、 pricate、protected...  golang中没有public、 pricate、protected...等关键字

                例子:

                图片.png

                

                图片.png


        2、系统保留关键字

                图片.png

        3、系统的预定义标识符

                图片.png


【原创】 第五章、Golang派生/复杂数据类型
15 10 2021

第五章、Go派生/复杂数据类型

        1、指针类型

            1.1 基本介绍

                a、对于基本类型来说,变量存的就是值,也叫值类型,基本数据类型在内存中的布局如下:

                图片.png

                b、获取变量的地址,使用&符号。比如,var i int = 10,获取i的地址:&i

                c、指针类型,指针变量存的是一个地址,这个地址指向的空间才是存的值;比如:var ptr *int = &num     在这里,带了* ptr是一个指针,没带*,ptr是整数。举例:指针在内存的布局

                图片.png

                d、获取指针类型所指向的值,使用 *,比如:var ptr *int ,使用*ptr获取ptr指向的值

                图片.png

            1.2 案例演示

                1.2.1 写一个程序,获取一个int变量num的地址,并显示在终端

                图片.png

                1.2.2 将num的地址赋值给指针ptr,并通过ptr去修改num的值

                图片.png

            1.3 指针细节说明

                a、值类型,都有对应的指针类型,形式为 *数据类型,比如int对应的指针类型就是 *int;*float32对应的指针类型就是 *float32;按此类推

                b、值类型包括:基本数据类型int系列、float系列、bool、string、数组和结构体struct

        2、值类型和引用类型

            2.1 常见的值类型和引用类型

                值类型:基本数据类型int系列、float系列、bool、string、数组和结构体struct

                引用类型:指针、slice切片、map、管道chan、接口interface等都是引用类型

            2.2 值类型和引用类型使用特点

                值类型:变量直接存储,内存通常在栈中(一般生命周期短的分配在栈区,但不绝对是,变量在别的函数用到,有可能放堆区,逃逸了)分配

                图片.png

                引用类型:变量存储的是一个地址,这个地址对应的空间才是真正存储的数据(值),内存通常在堆(一般生命周期长的分配在堆区,但不绝对是)上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收

                图片.png

                内存栈区和堆区示意图:

                图片.png


        3、数组

            3.1 基本介绍

                数组可以存放多个同一类型数据,数组也是一种数据类型,在Go中,数组是值类型

            3.2 数组定义和访问数组元素

                方式一、

                var 数组名 [数组长度]数据类型

                var chicken [5]float64

                赋值:chicken[0] = 10  chicken[1] = 20

                方式二、

                变量名 := [数组长度]数据类型{元素值1,元素值2,...} 

                a := [3]int{10,20,30}

                其他方式::

                var chicken [3]int = [3]int{10,20,30}

                var chicken  = [3]int{10,20,30}

                var chicken  = [...]int{5,6,7}

                指定元素值对应下标

                var name = [3]string{1:"tom",2:"LeSeein",3:"yasuo"}

                image.png

                访问数组中元素:chicken[0]     chicken[2]  

                

            3.3 数组在内存的布局

                image.png

                说明:

                a、数组地址可以使用&  取地址获得

                b、数组的第一个元素的地址就是数组的首地址

                c、数组的各个元素的地址间隔是依据数据的类型决定的,比如int 64位系统占用8个字节

                案例演示:

                image.png

            3.4 数组遍历

                方式一:for循环遍历

                image.png

                方式二:for - range方式遍历

                image.png

                案例:

                image.png

            3.5 数组使用细节和注意事项

                a、数组是多个相同类型数据组合,一个数组一旦声明/定义了,其长度是固定的,不能动态变化

                image.png

                b、var  arr []int ,这时候arr是一个slice切片

                c、数组中的元素可以试任何数据类型,包括值类型和引用类型,但是不能混合使用

                d、数组在创建后没有赋值是有默认值的(零值),数值类型默认0 , 字符串类型默认空字符串,bool数组默认false

                image.png

                e、使用数组的步骤: 1.声明数组并开辟空间   2.给各个元素赋值  3.使用数组

                f、数组的下标是从0开始的

                g、数组下标必须在指定范围内使用,否则报panic:数组元素超出长度,比如var arr [3]int,则有效下标为[0-2]

                h、在Go中,数组属于值类型,在默认情况下是值传递,因此会进行值拷贝,数组间不会互相影响

                主函数:

                image.png

                test函数:

                image.png

                数组值拷贝内存详解:

                image.png

                i、如果在其他函数中想修改原来数组的值,可以使用引用传递(指针方式)

                image.png

                image.png                

                函数中修改数组值内存详解:

                image.png

                j、长度是数组类型的一部分,在传递函数参数时,需要考虑数组的长度

                image.png

            3.6 数组应用案例

                image.png

            3.7 多维数组

                3.7.1 二维数组介绍(这里只介绍二维数组)

                3.7.2 二维数组声明、赋值

                image.png

                image.png

                image.png

                image.png


                3.7.3 二维数组应用

                image.png

                3.7.4 二维数组在内存的形式

                image.png

        4、切片

            4.1 在go中为什么需要切片?

            假如我们需要一个数组来保存学生成绩,但是学生人数不确定的情况又该怎么办呢?  解决方案:使用切片!!! 

            4.2 切片的基本介绍

            a、切片的英文是slice

            b、切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制

            c、切片的使用和数组类似,遍历切片、访问切片的元素和求切片的长度len(slice)都一样

            d、切片的长度是可以变化的,因此切片是一个可以动态变化的数组

            e、切片定义的基本语法

                var 切片变量名 []类型,比如:var num []int           

            image.png

            4.3 切片在内存中的形式

            image.png

            4.4 切片的使用

            方式一、定义一个切片,然后让切片去引用一个已经创建好的数组,

            image.png

            方式二、通过make来创建切片,基本语法:var 切片名 []type = make([],len,cap)

            说明:type:数据类型   len:大小      cap:指定切片容量,可选,如果分配了cap,则要求cap >= len

            image.png

            

            image.png

            内存布局:

            image.png

            以上两种方式轻易切片的区别:

            a、通过make方式创建的切片可以指定切片的大小和容量

            b、如果没有给切片的各个元素赋值,那么就会使用默认值[int、float=>0  string=>""   bool=>false]

            c、通过make方式创建的切片对应的数组是由make底层维护,对外不可见,即只能通过slice去访问各个元素


            方式三、定义一个切片,直接指定具体数组,使用原理类似make的方式

            image.png

            4.5 以上前两种方式的区别

            a、方式一时直接引用数组,这个数组是事先存在的,程序员是可见的

            b、方式二是通过make来创建切片,make也会创建一个数组,是由切片在底层进行维护,程序员是看不见的,make创建的切片示意图如下:

            image.png

            4.6 切片的遍历

            for循环遍历和for-range遍历

            image.png

            4.7 切片注意事项和细节说明

            a、切片初始化时,var slice = abc[startIndex : endIndex] ,从数组abc下标为 startIndex 开始, 取值到下标为endIndex元素,但不包括endIndex元素

            b、切片引用数组时,不能超过最大长度,范围在0~len(abc)之间,但是可以动态增加

                var slice = abc[0 : endIndex]  可以简写   var slice = abc[ :endIndex]

                var slice = abc[startIndex  : len(abc)]  可以简写   var slice = abc[ startIndex : ]

                var slice = abc[0: len(abc)]  可以简写   var slice = abc[ : ]

                image.png

            c、cap是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素

            d、切片定义后还不能使用,因为本身是一个空的,需要让其引用到一个数组,或者make一个空间供切片使用

            e、切片可以继续切片

                image.png

                image.png

            e、append()内置函数可以对切片进行动态追加

                image.png

                切片append()操作的底层原理分析:

                1、切片append操作的本质是对数组扩容

                2、go底层会创建一个新的数组newArr(安装扩容后的大小,再重新赋值给新的切片)

                3、将slice原来包含的元素拷贝到新的数组newArr

                4、slice重新引用到newArr

                5、newArr是在底层来维护,程序员是看不见的

                image.png

                image.png

                image.png

            f、切片的拷贝操作,使用copy内置函数实现拷贝

                image.png

                说明:

                1、copy(param1,param2)参数类型必须都是切片

                2、param1,param2 两个切片空间独立,互不影响

            g、元素多的切片拷贝给元素少的切片,一样没问题

                image.png

            4.7 string和slice的使用

                4.7.1 string底层是一个byte数组,因此string也可以进行切片处理

                image.png

                4.7.2 string和切片在内存的形式示意图

                image.png

                4.7.3 string是不可变的,也就是说不能通过str[0] = ‘q’方式来修改字符串

                4.7.4 如果要修改string字符串中某一个字符的值,可以转切片修改,修改以后再转string

                image.png

            4.7 切片练习

                image.png


        5、排序和查找

            5.1 排序基本介绍

                排序是指将一组数据,依照指定的顺序进行排列的过程

                第一类:内部排序(数据量比较小)

                将需要处理的所有数据都加载到内部存储器中进行排序,包括(交换式排序法、选择式排序法和插入式排序法)

                image.png

                案例:

                image.png

                第二轮的第一次比较基于第一轮最后一次比较的结果之上进行,以后每次比较同理...

                image.png

                代码:

                image.png                


                第二类:外部排序(数据量比较大)

                数据量过大,无法全部加载到内存中,需要借助外部存储进行排序,包括(合并排序法和直接合并排序法)

            5.1 查找基本介绍

                image.png

                5.1.1 顺序查找

                image.png

                5.1.2 二分查找(前提:有序数列!!!)

                思路分析:

                image.png

                每次折半查找

                image.png

                案例演示:

                image.png

        6、map

            6.1 基本介绍

            map是key-value的数据结构,又称为字段或者关联数组,官方称之为映射,类似其他编程语言的集合

            6.2 基本语法

            var map 变量名     map[keytype]valuetype

            keytype可以是什么类型::golang中map,key的类型又很多,比如:bool,数字,string,指针,channel,还可以是只包含前面几个类型的接口、结构体、数组, 通常为有int、string

            注意:slice、map还有function不可以,因为这几个没法用==来判断

            valuetype可以是什么类型::基本跟keytype一样的,通常为数字(整数、浮点数)、字符串、map、struct

            

            image.png

            注意:map跟数组不一样,数组声明以后就已经分配内存空间地址了

            6.3 案例演示

            image.png   

            说明:

            map在使用前一定要先make;map的key不能重复,重复了就是最后一个key-value值;map的value值可以试相同的;map的key-value是无序的

            6.4 map的使用方式

             image.png

            案例:

            image.png

            6.5 map的增删改查操作

            a、添加和更新

            image.png

            b、删除

            image.png

            注意:如果我们要删除map的所有key,没有一个专门的方法一次删除,可以遍历一下key,逐个删除,或者map = make(...),make一个新的,让原来的称为垃圾,被gc回收

            image.png

            c、查询

            查询有两个返回参数   var,findRes = names["num1"]  var就是查找的key对应的value值,findRes查找结果(值为true 和 false)

            image.png

            image.png

            image.png

            6.6 map遍历,只能使用for-range结构遍历,map的key不一定都是数字

            image.png

            6.7 map的长度统计,使用len函数

            image.png

            image.png

            6.8 map切片

            基本介绍:

            切片的数据类型如果是map,则我们称之为slice of map,map切片,这样使用则map这个数就可以动态变化了

            image.png

            6.9 map排序

            基本介绍:

            a、golang中没有专门的方法针对map的key进行排序

            b、golang中map默认是无序的,注意,也不是按照添加的顺序存放的,你每次遍历,得到的输出可能不一样

            c、golang中map的排序,是先将key排序,然后根据key值遍历输出即可

            image.png

            6.10 map使用细节说明

            a、map是引用类型,遵守引用类型传递机制,在一个函数接收map,修改后,会直接修改原来的值

            b、map容量达到后,再想map增加元素,会自动扩容,并不会发生panic,也就是说,map能动态的增加键值对

            c、map的value也经常使用struct类型,更适合管理一些复杂数据类型

            案例演示:

            image.png

            image.png

        7、管道channel

            7.1 基本介绍

            image.png

            image.png

            7.2 管道示意:

            image.png

            image.png

            image.png

            7.3 管道基本使用

            声明/定义channel:

            var 变量名  chan 数据类型   !!!


            var perChan chan *Person

            var intChan  chan int

            var mapChan chan map[int]string    (用于存放map[int]string类型数据)

            说明:

            1.channel是引用类型

            2.channel必须初始化才能写入数据,即make后才能使用

            3.channel是有类型的,intChan 只能写入int类型数据

            

            演示管道的使用:

            image.png

            image.png

            7.4 channel使用注意事项

            a、channel中只能存放指定的数据类型

            b、channel中数据放满了就不能再往里面存放数据了

            c、如果从channel中取出数据以后就可以继续存放

            d、在没有使用协程的情况下,如果channel数据取完了,再取,就会报dead lock


            7.5读写channel案例演示

            image.png

            image.png

            7.6 channel的遍历和关闭

            image.png

            image.png





        

            

            


            

            

            

            







【原创】 第四章、Golang基本数据类型
03 09 2021

第四章、Go基本数据类型

  第一章、数据类型基本介绍

   图片.png


        图片.png

        1、整数类型

            1.1 基本介绍

                简单的说,就是用来存放整数值得,比如,0,-1,139等

            1.2 整数类型有哪些

                Go语言内置了12种整数类型,分别是 byte、int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、uintptr,其中byte是uint8的别名

                图片.png

                

                int8范围测试:

                图片.png


                图片.png

                uint8范围测试:

                图片.png


                图片.png

                byte范围测试:

                图片.png

            1.3 整型使用细节

                a、整型分为有符号和无符号类型,int、uint

                b、golang的整型默认声明为int类型

                图片.png

                c、如何在程序中查看某个变量的字节大小和数据类型

                图片.png

            

                图片.png 

                d、golang程序中整型变量在使用时,遵循保小不保大的原则,即:保证程序正确运行的情况下,尽量使用占用内存空间小的数据类型

                e、bit:计算机中最小存储单位,byte:计算机中基本存储单元

                图片.png

                  

        2、浮点类型

            2.1 基本介绍

                小数类型/浮点类型就是用于存放小数的

            2.2 小数类型分类

                图片.png

                说明:

                a、浮点数在机器中的存放形式,浮点数=符号位+指数位+尾数位; 浮点数都是有符号的

                b、尾数部分可能丢失,造成精度损失,  如:-123.0000906;float64精度比float32精度高 

                图片.png

                c、浮点数的存储分为三部分:符号位+指数位+尾数位,在存储过程中,精度会有损失

            2.3 浮点型使用细节

                a、golang浮点型有固定的范围和字段长度,不受具体OS影响。

                b、golang浮点型默认声明为float64类型

                c、浮点型常量有两种表现形式

                十进制形式:5.69        0.896 / .896

                科学计数法形式:5.1234e2 = 5.1234 * 10 的2次方;9.56E-2 = 9.56 / 10的2次方

                d、通常情况使用float64,因为它比float32更精确

        3、字符类型(char)

            3.1 基本介绍

                golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来存。字符串就是一串固定长度的字符链接起来的字符序列,go字符串是由单个字节连接起来的;也就是说对于传统的字符串是由字符组成的,而go的字符串不同,它是由字节组成的!!!

                 Go内置两种字符类型:一种是byte的字节类类型(byte是uint8的别名),另一种是表示Unicode编码的字符rune,rune在Go内部是int32类型的别名,占用4个字节,Go语言默认的字符编码就是UTF-8,如果需要特殊的编码转换,则使用unicode/UTF-8标准包


            3.2 字符类型的使用

                图片.png


                图片.png


                图片.png

                说明:

                a、如果我们保存的字符在ASCII表内,如[0-9a-zA-Z],可以直接保存到byte

                b、如果我们保存的字符对应码值大于255,这时可以考虑使用int类型保存

                c、如果我们需要按照字符的方式输出,这时需要格式化输出,即:fmt.Printf(“c5=%c”,c5)

            3.3 字符类型使用细节

                a、字符常量是使用  单引号''  括起来的单个字符,列如:var byte c1 = 'a' ; var byte c2 = '9'; var int c3='中'

                b、go中允许使用转义字符‘\’来将其后的字符转义为特殊字符型常量。   列如:var c3 char = '\n'     // '\n'表示换行符

                c、go语言的字符使用UTF-8编码    UTF-8编码兼容ASCII码,在UTF-8编码中英文占用1个字节,汉字占用3个字节

                d、在go中,字符的本质是一个整数,直接输出时,是该字符对应UTF-8编码的码值

                e、可以直接给某一个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode字符

                图片.png

                f、字符类型是可以进行运算的,相当于一个整数因为它都对应又unicode码

                图片.png

                g、字符类型使用单引号 '' 把字符括起来

                golang按照unicode编码进行处理的,UTF-8是unicode码的具体实现

            3.4 字符类型本质探讨

                a、字符型存储到计算机中,需要将字符对应的码值(整数)找出来

                存储:字符 --> 转对应码值 --> 码值转二进制 --> 存储

                读取:二进制 --> 转对应码值 --> 找出字符 --> 读取 

                b、字符和码值的对应关系是通过字符编码表决定的(是规定好的)

                c、go语言的编码都同一成了utf-8,非常方便,再也没有编码乱码的困扰了

        4、布尔类型

            4.1 基本介绍

                布尔类型也叫bool类型,bool类型数据只允许取值true和false;布尔类型占用内存空间1个字节;bool类型多用于逻辑运算,一般用于程序流程控制(if流程控制语句、for循环控制语句)。

        5、字符串类型

            5.1 基本介绍

                字符串就是一串固定长度的字符链接起来的字符序列,go的字符串是单个字节连接起来的,go语言的字符串的字节使用UTF-8编码标识Unicode文本

            5.2 字符串的使用

                图片.png

            5.3 字符串使用细节

                a、go语言的字符串的字节使用UTF-8编码标识Unicode文本,golang统一使用UTF-8编码,中文乱码问题不会再困扰程序员

                b、字符串一旦赋值了就不能直接修改每一个元素,只能通过重新构造新的字符串并赋值给原来的字符串变量实现,在go中字符串是不可变的

                图片.png

                c、字符串的两种表示形式

                    1、双引号,会识别转义字符

                    图片.png

                    2、反引号,以字符串原生的形式输出,包括换行和特殊字符,可以实现防止攻击,输出源代码等效果

                    图片.png

                d、字符串拼接方式

                    图片.png

                e、当一行字符串太长时,需要使用到多行字符串,可以如下处理

                    图片.png

            5.4 字符串的常用操作

                image.png


        6、基本数据类型默认值(零值)

            6.1 基本介绍

                golang中,数据类型都有一个默认值,当程序员没有赋值时,就会使用默认值,在go中默认值也叫零值

            6.2 基本数据类型的默认零值如下:

                    图片.png

            6.3 演示基本数据类型输出默认值

                图片.png


        7、基本数据类型的转换

            7.1 基本介绍

                golang和java/c不同,go在不同类型的变量之间赋值需要显式转换(强制转换),也就是说golang中数据类型不能自动转换

            7.2 基本语法

                表达式T(v),将值v转换为类型T

                T就是数据类型,如:int32,int64,float64等等

                v就是需要转换的变量

            7.3 基本数据类型转换的案列

                图片.png

            7.4 基本数据类型转换的使用细节

                a、go中,数据类型的转换可以使范围小的 --> 范围大的; 也可以是范围大的 --> 范围小的

                b、被转换的是“变量存储的数据”(即值),变量本身的数据类型没有发生改变!

                c、在转换中,比如将int64转换为int8【-128 ~ +127】,编译时不会报错,只是转换结果按溢出处理,和我们希望的不一样。

                图片.png

                练习1:

                图片.png

                练习2:

                图片.png

                

                图片.png

            7.5 基本数据类型和string的转换

                7.5.1 基本数据类型转string

                    基本介绍:

                    在程序开发中,我们经常将基本数据类型转string,或者将string转基本数据类型

                    方式一:fmt.Sprintf("%参数",表达式)

                    函数介绍:

                    图片.png

                    案列演示:

                    图片.png

                    方式二:使用strconv包的函数

                    函数介绍:

                    图片.png

                

                    图片.png

                    案列演示:

                     图片.png

                    方式三:使用strconv.Itoa函数

                    图片.png


                7.5.2 string类型转基本类型

                    方式一:使用strconv包的函数

                    图片.png

                    案列演示:

                    图片.png

            7.6 注意事项

                在将string数据类型转换为基本数据类型时,要确保string类型能够转成有效的数据,比如:我们可以把“123”转成一个整数,不能把“hello”转成一个整数,如果强制转换,golang直接将其转为0,其它的一样的道理,float --> 0; bool --> false

                    图片.png




  

                

【原创】 第三章、Go语言基础知识
19 08 2021

第三章、Go语言基础语法

  第一、Golang概述

        1、Go语言结构

            1.1 Go语言的基础组成部分:

                包声明、引入包、函数、变量、语句&表达式、注释

        2、Go语言开发注意事项

                a、Go源文件以"go"为扩展名

                b、Go应用程序的执行入口是main()函数

                c、Go语言严格区分大小写

                d、Go方法有一条条语句构成,每个语句不需要加分号(Go语言会在每行后自动加分号)

                e、Go编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一行,否则报错

                f、Go语言定义的变量或者引用的包如果没有使用到,代码不能编译通过

                g、大括号成对出现,缺一不可

                h、源程序默认UTF-8编码

                i、定义函数以func开头,函数体开头的"{"不能换行

        3、Go语言转义字符(Escape character)

                a、\t :一个制表符,实现对齐的功能

                b、\n :换行符

                c、\\ :一个\

                d、\" :一个"

                e、\r :一个回车,fmt.Println("天龙八部雪山飞狐\r张飞")

                图片.png


        4、Go语言代码风格

            4.1 Go官方推荐使用行注释来注释整个方法和语句

            4.2 运算符两边习惯性各加一个空格,比如:2 + 3 * 5

            4.3 方法体后面的“{”不能换行,如下:

                图片.png

        5、Golang官方编程指南

            5.1 官方网站:https://golang.org

            5.2 Go语言中文文档:https://studygolang.com/pkgdoc

            5.3 Golang的包和源文件和函数的关系简图

                图片.png

            Golang中调用一个函数的方式:import引入包名, 再使用包名.函数的方式调用函数


        知识回顾

            1、Go语言的SDK是什么?

            SDK就是软件开发工具包

            2、Golang环境变量配置及其作用

            GOROOT:指定go sdk安装目录;GOPATH:golang的工作目录,我们项目的源码都放在GOPATH指定的目录下

            3、Golang程序的编写、编译、运行步骤是什么?

            编写:就是编写源码

            编译:go build 源码  -> 生成一个可执行文件

            运行:1.对可执行文件运行  xx.exe      2.go run 源码

            4、Golang程序的编写规则

                4.1 go文件后缀以.go结尾

                4.2 go程序区分大小写

                4.3 go语句后不需要带分号";"

                4.4 go定义的变量或者import包必须使用,如果没有使用就会报错

                4.5 go中不要把多条语句放在同一行,否则报错

                4.6 go中的大括号风格如下,不能换行

                图片.png

           

  第二、Golang变量

        1、Golang变量

            变量:使用一个名称来绑定一个内存地址,该内存地址中存放的数据类型由定义变量时指定的类型决定,该内存地址里面存放的内容可以改变。

            局部变量:在函数或方法内部定义使用的变量

            全局变量:在函数外部定义的变量

            变量定义了必须使用,不然编译会出错,但是全局变量定义了不使用是不会报错的

            变量三要素:变量名、值、数据类型


            1.1 变量使用步骤

                先声明变量、再给变量赋值、再使用变量

            1.2 变量使用的三种方式

                注意: 使用:=定义变量(:=方式只能在函数内部使用,并且左边的变量不应该是已经声明过的),此类声明变量的方式为短类型声明

                图片.png

            1.3 多变量声明

                图片.png

            1.4 声明全局变量(在函数外部声明的变量就是全局变量)

                图片.png

            1.5 变量使用注意事项

                1.5.1 变量在某区域数据值可以在同一类型范围内不断变化

                图片.png

                1.5.2 变量在同一作用域(在同一个函数或者代码块内)不能重名

                图片.png

                1.5.3 变量三要素:变量名、变量类型、变量值

                1.5.4 Golang的变量如果没有赋初值,编译器会使用默认值,比如:int默认值0,string默认值为空串,小数默认为0,               

                1.5.5 声明变量、初始化变量、给变量赋值操作

                声明变量:var i int      var num float32

                初始化变量:var a int = 50   var b = 400

                给变量赋值:比如先声明了变量var m int ,然后再给值   m = 100,这就是给变量赋值

            1.6 匿名变量

            image.png



        2、程序中+号的使用

            2.1 当+号左右两边都是数值类型时候,则做加法运算

            2.2 当+号左右两边都是字符串时候,则做字符串拼接

            图片.png

  第三、Golang常量

        1、Golang常量简介

                常量:使用一个名称来绑定一个内存地址,该内存地址里面存放的内容不可以改变,Go中常量分为布尔型、字符串型、数值型(整数型、浮点型和复数),使用const关键字定义常量

            1.1 常量基本介绍

                常量的定义格式:

                const identifier [type] = value   你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

                const b string = "abc"                    //显式类型定义

                const a,c = "abc","bcd"                  //隐式类型定义  

                常量还可以用作枚举:

                const(

                    Unhnow = 0        //性别未知

                    Female = 1          //女性 

                    Male = 2             //男性

                )

                常量可以用len(), cap(), unsafe.Sizeof()常量计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:

                iota,特殊常量,可以认为是一个可以被编译器修改的常量。

                在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。

                iota 可以被用作枚举值:

                图片.png

                第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2   

                可以简写为如下形式:

                 图片.png 

                image.png

                注意细节:

                细节1:

                image.png

                image.png

                细节2:

                image.png

                image.png

                细节3:

                image.png

                image.png

                细节4:

                image.png

                image.png

                细节5:

                image.png

                image.png

                细节6:

                image.png

                image.png


                总结::

                iota,特殊常量,可以认为是一个可以被编译器修改的常量;在每一个const关键字出现时,被重置为0;然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1; “const声明中,每新增一行代码行常量声明iota计数一次“;细节4中某一行声明了没有赋值,默认和上一行一致;一行中出现多个iota,当前行的iota只加1

                案例演示:

                图片.png

                第一行:1左移0位=1; 第二行:1左移10位 = 2的十次方  = 1024;...


  第四、复数类型

        1、复数类型基本介绍

            Go语言两种复数类型,分别是complex64、complex128,复数在计算机里面使用两个浮点数表示,一个表示实部一个表示虚部。complex64是由两个float32构成,complex128是由两个float64构成,复数的字面量表示和数学表示法一样

            complex64    32位实数和虚数  (复数)

            complex128    64位实数和虚数 (复数)

            图片.png

  第五、Go词法单元

            1.3.1 token

                token是构成源程序的基本不可分割的单元,编译器编译程序的第一步就是将源程序分割为一个独立的token,这个过程叫词法分析,Go语言的token可分为关键字、标识符、操作符、分隔符和字面常量等。

                Go的token分隔符有两类,一类是操作符还有一种自身没有特殊含义仅用来分隔其他token,被称为纯分隔符。

                sum := a+b   “:=”“+”既是分隔符也是token,所以这个简单的语句被分为5个token: "sum"、“:=”、“+”、“a”、“b”

                纯分隔符:空格、制表符、换行符、回车符,多个相邻的空格或制表符会被编译器看做分隔符处理。

                    图片.png



 






【原创】 第二章、在各系统中安装Go
20 03 2021

第二章、Go安装

        1、windows平台下载Go安装包

            https://studygolang.com/dl

        1.1 安装

          图片.png



            图片.png

            

            图片.png


            图片.png


            图片.png


            图片.png


            

                图片.png            

            

            图片.png


            查看go版本 

             图片.png

        1.2 配置环境变量

            图片.png

            开启go mod模式:

            go env -w GO111MODULE=on

            设置国内代理:

            go env -w GOPROXY=https://goproxy.cn,direct

            图片.png


            Administrator的用户变量:只针对这个用户;系统变量:针对所有的用户变量都生效


图片.png

            

            查看环境

            图片.png


        2、Go语言命令行工具介绍

            go build:用于编译源码文件、代码包、依赖包

            go run:可以编译并运行Go源码文件

            go get:命令主要是用来动态获取远程代码包

        3、在linux平台下安装Go

            3.1 下载安装包

                https://studygolang.com/dl

                wget https://studygolang.com/dl/golang/go1.16.2.linux-amd64.tar.gz

                cd /usr/local/

            3.2 解压:

                tar -zxvf go1.16.2.linux-amd64.tar.gz

                图片.png

            3.3 配置环境变量

                配置环境变量:

                vi /etc/profile

                export GOROOT=/usr/local/go
                export GOPATH=/home/go
                export PATH=$PATH:$GOROOT/bin:$GOPATH/bin


                图片.png

            3.4 查看go版本和环境变量

                go version

                图片.png

               go env

                图片.png


        4、在linux中创建第一个go程序

            4.1.1 创建工作目录,建议在/home/go目录,  并且创建三个目录:bin(编译后的可执行文件的存放路径)  pkg(编译包时,生成的.a文件的存放路径)  src(源码路径,我们的工程一般创建在src目录下面)

            4.1.2 创建测试文件

            图片.png

            4.1.3 构建工程

            图片.png

            4.1.4 命令行直接输入编译文件的文件名

            图片.png


        5、编译

            image.png


        6、交叉编译

            image.png

            image.png

            

 

             

            


【原创】 第一章、初识Go语言
19 03 2021

第一章、Go语言简介

一、初识Go语言

        1、简介

                Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言

              罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在LinuxMac OS X平台上进行了实现,后来追加了Windows系统下的实现。

        2.描述

                Go的语法接近C语言,但对于变量的声明有所不同。Go支持垃圾回收功能。Go的并行模型是以东尼·霍尔通信顺序进程(CSP)为基础,采取类似模型的其他语言包括OccamLimbo,但它也具有Pi运算的特征,比如通道传输。在1.8版本中开放插件(Plugin)的支持,这意味着现在能从Go中动态加载部分函数。

与C++相比,Go并不包括如枚举异常处理继承泛型断言虚函数等功能,但增加了 切片(Slice) 型、并发、管道、垃圾回收、接口(Interface)等特性的语言级支持。Go 2.0版本将支持泛型,对于断言的存在,则持负面态度,同时也为自己不提供类型继承来辩护。

不同于Java,Go内嵌了关联数组(也称为哈希表(Hashes)或字典(Dictionaries)),就像字符串类型一样。
        3.撰写风格        

                在Go中有几项规定,当不匹配以下规定时编译将会产生错误。

        a、每行程序结束后不需要撰写分号(;)。

        b、大括号({)不能够换行放置。

        c、if判断式和for循环不需要以小括号包覆起来。

Go亦有内置gofmt工具,能够自动整理代码多余的空白、变量名称对齐、并将对齐空格转换成Tab。

        4.编译器

                当前有两个Go编译器分支,分别为官方编译器gc和gccgo。官方编译器在初期使用C写成,后用Go重写从而实现自举。Gccgo是一个使用标准GCC作为后端的Go编译器。

官方编译器支持跨平台编译(但不支持CGO),允许将源代码编译为可在目标系统、架构上执行的二进制文件。

        5.Go语言能做什么

                服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。

                分布式系统、数据库代理器、中间件等,例如Etcd。

                网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用,而且Go内置的net/http包基本上把我们平常用到的网络功能都实现了。

        6.解释型语言与编译型语言的区别

                编译型语言已经提前编译成二进制代码了,执行效率更高

            image.png

        7.Go项目结构

            个人开发:

            image.png

            image.png


            企业开发:

            image.png