Go语言基础 | 青训营笔记

505 阅读5分钟

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

引言

今天的课程先是介绍了Go的相关背景和发展情况,之后主要是学习Go语句的一些基础语法和3个较为复杂的实战案例,这篇文章主要是针对今天课程的记录和总结。


一、本堂课重点内容

本堂课的知识点

基础知识

  • 变量

声明:

var name type   //var 变量名 变量类型 
//举例
var a, b *int
//批量声明
var (
    a int
    b string
    c []float32
    d func() bool
    e struct {
        x int
    }
)
  • if elseif else
if condition1 {
    // do something
} else if condition2 {
    // do something else
}else {
    // catch-all or default
}
  • 循环只有for语句
  • swith case中无需增加break
  • 数组
  • 切片
  • 映射 键值对 map
  • range关键字在循环遍历时的用法
  • 函数
  • 指针
  • 结构体和结构体方法
  • 错误处理(类似java中的异常的作用)
  • 字符串操作和字符串格式化
  • JSON处理
  • 时间处理
  • 数字解析
  • 获取系统中进程信息,对进程进行管理

二、详细知识点介绍

  1. 数组

在Go语言中数组是值类型,值传递。 即通过一个数组对另一个数组进行复制(=),是值复制,两个数组的数据存储在各自不同的地址空间

var 数组变量名 [元素数量]Type
//举例
var team [3]string
team[0] = "hammer"
team[1] = "soldier"
team[2] = "mum"

for k, v := range team {  //利用 range k代表下标 v代表当前下标对应的值
    fmt.Println(k, v) 
}
  1. 切片

切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型

slice [开始位置 : 结束位置]
var a  = [3]int{1, 2, 3}
fmt.Println(a, a[1:2])
//其中 a 是一个拥有 3 个整型元素的数组,被初始化为数值 1 到 3,使用 a[1:2] 可以生成一个新的切片,代码运行结果如下:
[1 2 3]  [2]
  1. 结构体和结构体方法

结构体是一种复合的基本类型,通过 type 进行定义,其属于值类型

type 类型名 struct {
  字段1 字段1类型
  字段2 字段2类型
  …
}

匿名结构体

package main
     
import (
    "fmt"
)
     
func main() {
    var user struct{Name string; Age int}
    user.Name = "小王子"
    user.Age = 18
    fmt.Printf("%#v\n", user)
}

在Go语言中,访问结构体指针的成员变量时可以继续使用.,**这是因为Go语言为了方便开发者访问结构体指针的成员变量,使用了语法糖(Syntactic sugar)技术,将 ins.Name 形式转换为 (*ins).Name。

type Player struct{
    Name string
    HealthPoint int
    MagicPoint int
}

tank := new(Player) 
//tank := &(Player) //&和利用new是一样的操作,返回的是结构体指针类型
tank.Name = "Canon"
tank.HealthPoint = 300
  1. 错误处理

错误表示程序中出现了异常情况。比如当我们试图打开一个文件时,文件系统里却并没有这个文件。这就是异常情况,它用一个错误来表示。 在 Go 中,错误是很常见的。错误用内建的 error 类型来表示。

package main

import (  
    "fmt"
    "os"
)
func main() {  
    f, err := os.Open("/test.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(f.Name(), "opened successfully")
}

//open函数原型
func Open(name string) (file *File, err error)

在处理错误时,通常都是将返回的错误与 nil 比较。nil 值表示了没有错误发生,而非 nil 值表示出现了错误

  1. map

Go语言中 map 是一种特殊的数据结构,一种元素对(pair)的无序集合,pair 对应一个 key(索引)和一个 value(值),所以这个结构也称为关联数组或字典,这是一种能够快速寻找值的理想结构,给定 key,就可以迅速找到对应的 value。

map这种数据结构在Python称为字典,在Java中也有Map,HashMap等

在Go语言中map属于引用类型

举例:

make(map[KeyType]ValueType, [cap])
//其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。


func main() {
	scoreMap := make(map[string]int, 8)
	scoreMap["张三"] = 90
	scoreMap["小明"] = 100
	fmt.Println(scoreMap)
	fmt.Println(scoreMap["小明"])
	fmt.Printf("type of a:%T\n", scoreMap)
}
  1. JSON处理

现如今,都是利用JSON格式来保存和传送数据,在Go中利用结构体对应JSON中的对象,然后利用Marshal函数来实现结构体实例化变量转为JSON格式

type userInfo struct {
	Name  string
	Age   int `json:"age"`
	Hobby []string
}
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)

三、实践练习例子

主要是学习课堂的例子和后面的3个实战例子,对于第三个实战例子中使用到的标准库和函数还是有一些不熟悉。 第一个例子中的输入,改为使用fmt.Scanf

package main

import (
   "fmt"
   "math/rand"
   "time"
)

func main() {
   maxNum := 100
   rand.Seed(time.Now().UnixNano())
   secretNumber := rand.Intn(maxNum)
   fmt.Println("Please input your guess")
   for {
      var guess int
      fmt.Scanf("%d\n", &guess)  
      fmt.Println("You guess is", guess)
      if guess > secretNumber {
         fmt.Println("Your guess is bigger than the secret number. Please try again")
      } else if guess < secretNumber {
         fmt.Println("Your guess is smaller than the secret number. Please try again")
      } else {
         fmt.Println("Correct, you Legend!")
         break
      }
   }
}

在循环中,利用fmt.Scanf 要记得使用\n代表换行结束,否则默认还会读取回车换行。

四、课后个人总结

这堂课程下来,让我对于Go语言的基础语法有了印象,之后主要是对于数组,切片,map映射,结构体和函数的理解有感触了。 3个实战案例的后两个让我学习到Go实现服务端和简单实现服务器的步骤,看到了Go在网络编程上的便利和快捷。

五、引用参考

主要参考了青训营课程资料和Go语言中文网中的相关资料