【Day 1】 走进Go语言基础语言 | 青训营笔记

58 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

一、本堂课重点内容:

1.Golang特点

2.Golang基础语法

二、详细知识点介绍:

1.Go语言的特点:

(1)高性能、高并发

                性能媲美c++、Java,且不需要第三方库来提供高性能服务,仅用标准库即可实现高性能、高并发开发

(2)语法简单、学习曲线平缓

                语法与c语言相似度高,且摒弃了一些繁杂的c语言的语法,容易上手

(3)丰富的标准库

                Golang有如python一样丰富的标准库,且具有很高的稳定性与兼容性的保障,降低了开发的成本

(4)完善的工具链

                无论是编译、代码格式化、文档管理、错误检查、代码补充提示,都有对应的工具,且还有完整的代码测试框架

(5)静态链接

                Golang编译结果默认静态链接。只需要拷贝编译后唯一一个可执行文件,即可部署运行,方便快捷

(6)快速编译

                Golang具有静态语言中几乎最快的编译速度

(7)跨平台

                Golang能在多种不同的操作系统下运行,包括安卓、Linux、Windows、Macos以及一些奇奇怪怪的设备上运行,还能配置交叉编译环境

(8)垃圾回收

                Golang配有垃圾回收机制,在写代码时无需考虑内存的分配与释放

2.Go语言基础语法(易忘点):

(1)声名

                 Go语言主要有四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数实体对象的声明。

(2)Slice

           Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已。

           内置的append函数用于向slice追加元素:

               var x []int

                x = append(x, 1)

                x = append(x, 2, 3)

                x = append(x, 4, 5, 6)

                x = append(x, x...) // append the slice x

                fmt.Println(x) // "[1 2 3 4 5 6 1 2 3 4 5 6]"

(3)Map

            内置的make函数可以创建一个map:

                    a.ages := make(map[string]int)

                    b.ages := map[string]int{

                        "alice": 31,

                        "charlie": 34,

                        }

         使用内置的delete函数可以删除元素:delete(ages, "alice")

     Map的迭代顺序是不确定的,并且不同的哈希函数实现可能导致不同的遍历顺序。

(4)  JSON

    JavaScript对象表示法(JSON)是一种用于发送和接收结构化信息的标准协议。

    Go语言对于这些标准格式的编码和解码都有良好的支持,由标准库中的encoding/json、encoding/xml、encoding/asn1等包提供支持

    基础类型可以通过JSON的数组和对象类型进行递归组合。一个JSON数组是一个有序的值序列,写在一个方括号中并以逗号分隔;一个JSON数组可以用于编码Go语言的数组和slice。一个JSON对象是一个字符串到值的映射,写成一系列的name:value对形式,用花括号包含并以逗号分隔;JSON的对象类型可以用于编码Go语言的map类型(key类型是字符串)和结构体。例如:

            boolean                      true

                number                      -273.15

               string                          "She said "Hello, BF""

                array                           ["gold", "silver", "bronze"]

                object                         {"year": 1980,

                                                    "event": "archery",

                                                    "medals": ["gold", "silver", "bronze"]}

            考虑一个应用程序,该程序负责收集各种电影评论并提供反馈功能。它的Movie数据类型和一个典型的表示电影的值列表如下所示。

type Movie struct {

                    Title              string

                    Year              int json:"released"

                   Color            bool json:"color,omitempty"

                    Actors          []string

                }

                var movies = []Movie{

                    {Title: "Casablanca", Year: 1942, Color: false,

                       Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}},

                    {Title: "Cool Hand Luke", Year: 1967, Color: true,

                        Actors: []string{"Paul Newman"}},

                    {Title: "Bullitt", Year: 1968, Color: true,

                        Actors: []string{"Steve McQueen", "Jacqueline Bisset"}},

                        // ...

                }

将一个Go语言中类似movies的结构体slice转为JSON的过程叫编组(marshaling)。编组通过调用json.Marshal函数完成,返回一个编码后的字节slice,包含很长的字符串

                     使用json.Unmarshal函数来将JSON格式的字符串解码为字节slice

(5)  匿名函数

            函数字面量允许我们在使用函数时,再定义它。通过这种技巧,我们可以改写之前对strings.Map的调用:strings.Map(func(r rune) rune { return r + 1 }, "HAL-9000")

(6)可变参数

            在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符号“...”,这表示该函数会接收任意数量的该类型参数。

       func sum(vals ...int) int {

                total := 0

                for _, val := range vals {

                total += val

                }

                return total

            }

(7)Deferred函数

            你只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。当执行到该条语句时,函数和参数表达式得到计算,但直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反。

通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后。

(8)Panic异常

           Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等。这些运行时错误会引起painc异常。

一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(可以先理解成线程,在第8章会详细介绍)中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。

不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常;panic函数接受任何值作为参数。当某些不应该发生的场景发生时,我们就应该调用panic。比如,当程序到达了某条逻辑上不可能到达的路径

(9)Recover捕获异常

通常来说,不应该对panic异常做任何处理,但有时,也许我们可以从异常中恢复,至少我们可以在程序崩溃前,做一些操作。举个例子,当web服务器遇到不可预料的严重问题时,在崩溃前应该将所有的连接关闭;如果不做任何处理,会使得客户端一直处于等待状态。如果web服务器还在开发阶段,服务器甚至可以将异常信息反馈到客户端,帮助调试。

如果在deferred函数中调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。

三、课后个人总结:

    通过本堂课的学习,本人对Golang的优点、基础语法在理论上有了基础的了解,接下来即将进入工程项目实战课程的学习,争取通过实践加深对Golang的理解

四、参考文档

     Go语言圣经(中文版)