Go-语言基础&实战案例| 青训营笔记

74 阅读4分钟

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

一、本堂课重点内容:

基础知识
  • var
  • for
  • if
  • switch
  • array
  • slice
  • map
  • range
  • func
  • struct
  • struct-method
  • error
  • string
  • json
  • time
  • strconv
  • env
  • image
  • import
基础实践
  • guessing-game 猜谜游戏
  • simpledict 命令行词典
  • proxy SOCKS5 代理

二、详细知识点介绍:

声明
  • 当一个计算机程序需要调用内存空间时,对内存发出的“占位”指令,称为:“声明”。
  • 从根本上说,静态类型和动态类型语言的最大区别就是,数据类型是否在编译时确定。
for 循环
for j := 7; j < 9; j++ {
    // 循环体
   }
  • 初始赋值;循环条件;循环后加分 省略哪个都可以。
if 判断
if num := 9; num < 0 {
   // false
} else if num < 10 {
   // true
} else {
   // false
}
  • 初始赋值;判断条件 初始赋值可省略。
  • 如果不满足,可接下来判断else。
switch 判断
a := 2
switch a {
case 1:
   // 1
case 2:
   // 2
case 3:
   // 3
case 4, 5:
   // 4,5
default:
   // other
}
  • 多种情况判断的语法。
array
  • 数组的声明
// 创建一个[0:4] int类型的数组a
var a [5]int
  • 数组下标赋值
a[4] = 100
  • 数组下标的使用
fmt.Println("get:", a[2])
  • 数组由于声明时需要固定大小,所以在go语言当中并不常用,slice更深得人心。
  • 数组的索引从0开始,因此索引的取值范围应该是从0至数组元素个数减1为止。如本例则为0、1、2、3。超出范围的赋值和取值将引发下标越界错误,导致程序出错。对某一索引位置的元素重复赋值将导致旧值被新值替换。
slice
  • 切片的声明
var s []int
// 上面是个空切片 当添加值时 会自动扩容
s := make([]string, 3)
  • 添加切片的值 值得一提的是,append()函数本身并不会改变原有切片,只是将切片“扩容”后的结果作为函数返回值。因此,需要将“扩容”后的结果再次(即函数返回值)赋值给slice_name,才能真正使slice_name发生改变。
s = append(s, "d")
  • 与数组不同,为切片赋值可以理解为“扩充”。在一开始,切片里面的元素个数为0。“扩充”一个值,就相当于为切片中的第一个元素赋值。赋值后,切片的元素个数就变成了1。若再次“扩充”,则相当于为切片中的第二个元素赋值。赋值后,切片的元素个数就变成了2,以此类推
map
  • 集合的声明 集合可以看作是一类特殊的切片,只不过集合的元素都是由若干“键-值对”数据构成的。所谓“键”,相当于“唯一ID”;“值”,相当于单条数据,键不允许重复
m := make(map[string]int)
  • 值得一提的是,若对一个已经存在数据的“键”再次赋值,原有的数据将被覆盖
range
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums { // 求该值索引序号
   sum += num // 求和
   if num == 2 {
      fmt.Println("index:", i, "num:", num) // index: 0 num: 2
   }
}
  • for循环仅适用于数组和切片的元素遍历
  • for-range结构适用于数组、切片和集合
func
  • 函数声明
func add(a int, b int) int {
   return a + b
}
// 变量都是在各自的函数体内声明和使用的,无法共用,只是凑巧名称和类型都一样而已。大家不要将它俩混为一谈。
struct
  • 结构体声明
type user struct {
   name     string
   password string
}
  • 结构体使用
func checkPassword(u user, password string) bool {
   return u.password == password
}

func checkPassword2(u *user, password string) bool {
   return u.password == password
}
  • 值传递 直接传递一个变量名到另一个函数中,属于值传递。按照Go代码的执行策略,发生值传递时,将在另一个函数中自动生成一个值的副本。
  • 引用传递 与值传递相对的便是引用传递,这种方式在函数间传递的是指针,而指针恰恰是内存地址。这样的传值,无论发生在多少个函数之间,改变将始终作用于相同地址的数据上。
struct-method
  • 结构体方法声明
func (u user) checkPassword(password string) bool {
   return u.password == password
}

func (u *user) resetPassword(password string) {
   u.password = password
}
error
string
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
json
time
now := time.Now()
fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
fmt.Println(t)                                                  // 2022-03-27 01:25:36 +0000 UTC
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
fmt.Println(t.Format("2006-01-02 15:04:05"))                    // 2022-03-27 01:25:36
diff := t2.Sub(t)
fmt.Println(diff)                           // 1h5m0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
if err != nil {
   panic(err)
}
fmt.Println(t3 == t)    // true
fmt.Println(now.Unix()) // 1648738080
strconv
env
image
import

三、实践练习例子:

guessing-game 猜谜游戏
simpledict 命令行词典
proxy SOCKS5 代理

四、课后个人总结:

  • 本章有什么知识点不容易掌握?
  • 什么地方容易与其他内容混淆?