go语言基础语法 | 青训营笔记

416 阅读6分钟

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

一、本堂课重点内容:

  • go语言基础语法

二、详细知识点介绍:

变量

go语言是一门强类型语言,每一个变量都有它自己的变量类型。

常见类型

字符串(string),整数(int),浮点型(float),布尔(bool)型等

变量声明

go语言变量的声明有两种方式。

  1. 通过var 变量名 变量类型 的形式来声明变量
  2. 通过变量名 := 初始值的形式来声明变量,此时一定要进行初始化,go会通过初始值来推断变量类型,如果有需要也可以写出变量类型

if else

go语言里面的if else写法和C或者C++类似。但有两点不同之处。

  1. if后面不需要加括号。if(条件)是错的,if 条件即可
  2. if后面必须接大括号。c/c++里if后面可以直接接上一个语句,但在go里是不行的,必须接上大括号

循环

不同于c/c++,go里面只有for循环,没有while循环。

for循环有以下三种常用写法

  1. for {}代表死循环,与c/c++的while(true){}相同
  2. for 单次表达式;条件表达式;末尾循环体 {} 这与c/c++类似,例如for i:=1; i <= 100; i++ {}
  3. for 条件表达式 {}其实是2省略了单次表达式和末尾循环体,与c/c++的while(条件表达式) {}相同

switch

结构与c/c++的类似,但有以下不同之处

  1. 在go里面,switch case只会执行对应的case,然后就会退出switch,但是在c/c++里不加上case会继续往下执行程序
  2. 在go里面,switch case的case类型可以使用任意类型,但在c/c++,它只能是整数
  3. go可以在switch后面不加任何的变量,然后在case里面写条件分支,这可以用来代替if-else,并且逻辑更为清晰

数组

数组就是一个具有编号且长度固定的元素序列。

定义一个数组可以用var 变量名 [数组大小]变量类型

切片

  • 切片不同于数组可以任意更改长度,然后也有更多丰富的操作。
  • 使用make来创建切片,格式为slice1 := make([]类型),也可以直接指定长度。
  • 切片可以用append来追加元素,例如s = append(s, 'd')
  • 切片实际上是一个存储了长度、容量,以及指向一个数组的指针的结构体。
  • 切片拥有像python一样的切片操作,例如s[2:5]是取出s的第3-5(下标为2-4)的元素。但是不支持负数索引

map

map即为哈希表。

  • 使用make来创建一个空map,m := make(map[key]val),其中key为map 的键值,val为存储的值类型
  • 使用delete来删除map中的键值对,delete(map, key),其中map为具体变量,key为所对应key值类型
  • go的map是完全无序的,遍历的时候不会按照字母顺序,也不会按照插入顺序输出,而是随机顺序

range

对于一个切片或者是map来说,可以用range来遍历它们,这样代码更为简洁。

  • range遍历的时候,对于数组会返回两个值,第一个是索引,第二个是对应位置的值,不需要索引时可以用_来忽略。

函数

go中函数的定义格式为func 函数名(变量名1 变量类型1, ...) 返回类型 {}。例如

 func add(a int, b int) int {
     return a+b
 }

即为一个两个变量相加的函数。

  • go里面的函数原生支持返回多个值
  • 在实际的业务逻辑代码里面几乎所有的函数都返回两个值,第一个是真正的返回结果,第二个值是一个错误信息。

结构体

go中结构体的定义为

 type 结构体名 struct {
     变量名1 类型1
     变量名2 类型2
     ...
 }
 type user struct {
     name string
     password string
 }

结构体构造时需要传入字段的初始值,可以用这种键值对的方式去指定初始值。

 a := user{name:"wang",password:"1024"}
 b := user{"wang","1024"}
 c := user{name:"wang"}

结构体方法

go里面的结构体方法类似于其他语言里的类成员函数。

具体的格式在基础函数格式的函数名前加上括号,里面填入结构体,例如

 func (u user) checkPassword(password string) bool {
     return u.password == password
 }

错误处理

go习惯使用一个单独的返回值来传递错误信息。

不同于java自家家使用的异常。go语言的处理方式,能够很清晰地知道哪个函数返回了错误,并且能用简单的if else来处理错误。

在函数里面,我们可以在那个函数的返回值类型里面,后面加一个error,就代表这个函数可能会返回错误。

字符串操作与字符串格式化

go的标准库strings包里面有很多常用的字符串工具函数。

 a := "hello"
 fmt.Println(strings.Contains(a, "ll"))                // true
 fmt.Println(strings.Count(a, "l"))                    // 2
 fmt.Println(strings.HasPrefix(a, "he"))               // true
 fmt.Println(strings.HasSuffix(a, "llo"))              // true
 fmt.Println(strings.Index(a, "ll"))                   // 2
 fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
 fmt.Println(strings.Repeat(a, 2))                     // hellohello
 fmt.Println(strings.Replace(a, "e", "E", -1))         // hEllo
 fmt.Println(strings.Split("a-b-c", "-"))              // [a b c]
 fmt.Println(strings.ToLower(a))                       // hello
 fmt.Println(strings.ToUpper(a))                       // HELLO
 fmt.Println(len(a))                                   // 5

go的标准库的fmt包,里面有很多的字符串格式相关的方法。例如fmt.Printf便是类似于c/c++的printf。

此外在go中可以使用%v来打印任意类型变量,%+v打印详细的结果,%#v打印更详细的结果。

 ype point struct {
         x, y int
     }
     s := "hello"
     n := 123
     p := point{1, 2}
     fmt.Println(s, n) // hello 123
     fmt.Println(p)    // {1 2}
 ​
     fmt.Printf("s=%v\n", s)  // s=hello
     fmt.Printf("n=%v\n", n)  // n=123
     fmt.Printf("p=%v\n", p)  // p={1 2}
     fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
     fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}

JSON处理

go语言里面的JSON操作非常简单,对于一个已有的结构体,我们可以什么都不做,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用json.Marshaler去序列化,变成一个JSON的字符串。

序列化之后的字符串也能够用json.Unmarshaler去反序列化。

默认序列化出来的字符串的话,它的风格是大写字母开头,而不是下划线。我们可以在后面用json tag等语法来去修改输出JSON结果里面的字段名。

时间处理

  • 使用time.Now获取当前时间
  • 使用time.Date构造一个带时区的时间
  • 使用Sub求取两个时间的差,即时间段,再用Year、Month、Day、Hour等函数去获取时间段对应单位的数量
  • 使用time.Unix获取时间戳

数字解析

使用strconv这个包进行字符串数字之间的转换。

常见有Atoi和Itoa两个函数。

进程信息

  • 使用os.Argv来获取程序启动时的命令行参数
  • 使用os.Getenv和os.Setenv来获取环境变量和设置环境变量

杂项

  • go的字符串可以通过"+"来连接,与py,java类似
  • go能够直接去打印一个数组、map、结构体等

三、实践练习例子:

猜字谜游戏

大体上是使用当前时间作为种子生成一个小于100随机数作为最终答案,不断获取用户输入并反馈用户输入与最终答案的大小关系,直至用户猜到最终答案。

涉及到的知识点有时间处理错误处理字符串操作与格式化循环结构分支结构等。

在线字典

利用彩云翻译的api,通过go的JSON处理和http请求以及命令行参数,获取到传入参数的英文单词的一些信息。

涉及到的知识点有切片字符串处理与格式化JSON处理进程信息等。

四、课后个人总结:

在在线字典里使用了两个网站来快速生成代码。

一个是Convert curl to Go用来生成等效curl命令行的go代码,一个是Json2go用来生成等效JSON文件的go结构体。

这两者自己实现的话要花费大量时间精力,恰恰说明了在实际开发过程中,运用合适的工具可以大大减少开发周期,提升开发效率。