Go语言基础 | 青训营笔记

109 阅读5分钟

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

本文将简单记录《Go 语言基础一基础语法》所学,以及对应的补充说明。

1. 什么是 Go 语言

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

Go 语言适合进行服务器编程、网络编程、分布式系统……

2. 基础语法

2.1 Hello Wrold

通过一个最简单的 hello wrold 程序上手 go 语言

package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world")
}
  • package xxx
    • 表示这个文件属于 main 包的一部分,go 项目是通过包进行组织的,多个文件可以同属一个包。
    • main 是程序的入口包,其中的 main 函数是程序的入口函数(与 C 语言相似)
  • import xxx
    • 表示导入包,可以是 go 标准库的包(如:fmt),也可以是自定义或是从第三方下载的包
  • fmt.Println()
    • fmt 是我们导入的包,fmt.Println() 则表示调用 fmt 这个包中的 Println 这个函数
    • 在一个包内,若函数名以大写字母开头,则这个函数默认是导出的,可被其它包调用,若以小写字母开头,则只能供本包的函数调用。

2. 2 变量

Go 语言是强类型语言,内置变量类型有:intfloat32bytestring 等,详细介绍可参考这里

声明变量的两种方式:

  1. 使用 var 变量名 类型 = 表达式 语句声明变量(以 string 类型为例)

    • var s string
    • var s = ""
    • var s string = "" 其中 类型= 表达式 可以省略一个。
  2. 使用 变量名 := 表达式 语句声明变量

    • learn := "juejin"
    • year := 2023 变量的类型会根据表达式的值自动推导。

2.3 if-else

a := 8
if a % 2 == 0 {
    fmt.Println("%v是个偶数", a)
} else {
    fmt.Println("%v是个奇数", a)
}

if 后面不接括号,且 {} 不可省略

在执行条件判断之前可以执行一条简短的语句,以上代码可以合并成下面这种形式:

if a := 8; a % 2 == 0 {
    fmt.Println("%v是个偶数", a)
} else {
    fmt.Println("%v是个奇数", a)
}

2.4 循环

Go 语言中只有一种循环,for 循环。没有 whiledo while。以下是 C 语言类型的三段式结构:

for i := 0; i < 10; i++ {
    fmt.Println(i)
}

if 一样,for 后面不需要接 (),其中的三段任何一段都可以省略,全部省略则与 while 等效:

for {
    // something
}

同样,在循环体内可以通过 breakcontinue 跳出或者继续循环

2.5 switch

iffor 语句一致,switch 后不需要加 ()。需要注意的是,在 Go 语言中,只会执行满足条件的 case 语句,并不需要 break 语句截断,这一点与 C 语言不同。

a := 8
switch a % 2 {
case 0:
    fmt.Println("%v是个偶数", a)
case 1:
    fmt.Println("%v是个奇数", a)
default:
    fmt.Println("other")
}

Go 语言的 switch 更加灵活,switch 后可以不加变量,而是在 case 中写条件分支:

a := 8
switch {
case a % 2 == 0:
    fmt.Println("%v是个偶数", a)
case a % 2 == 1:
    fmt.Println("%v是个奇数", a)
default:
    fmt.Println("other")
}

2.6 数组

在 Go 语言中数组的大小在变量声明后就不能改变,而且数组为值类型,如果将数组作为参数传给函数,实际上传的是数组的拷贝,而不是指针,这与 C 语言不同。

// 声明数组变量
var a [5]int

// 声明数组变量并赋初值
b := [5]int{1, 2, 3, 4, 5}

// 修改值
a[0] = 1

// 求数组长度
lenth := len(a)

// 二维数组
var c [2][3]int

值得一提的是,声明数组变量时必须指定其大小,否则声明的就是切片,即使是声明的同时初始化数组,也需要指定数组大小,这点与 C++不同。

// C++ 数组
int a[] = {1, 2, 3, 4, 5}

2.7 slice

slice 切片在 Go 语言中是引用类型,是一个动态的指向数组切片的指针,切片的大小可以动态调整。声明切片方式与声明数组的方式相似,但不需要指定大小:

// 声明切片
var primes []int

// 声明切片并赋初值
primes := []int{2, 3, 5, 7, 11, 13}

我们也可以用 make 来创建切片,此时可以指定切片的初始大小

s := make([]string, 3)

可以像数组一样赋值

s[0] = "a"
s[1] = "b"
s[2] = "c"

切片的大小可以动态调整,但需要注意的是进行 append 操作时需要将返回值赋给切片本身。

fmt.Println(len(s)) // 3
s = append(s, "d", "e")
fmt.Println(len(s)) // 5

可以进行截取

fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5])  // [a b c d e]
fmt.Println(s[2:])  // [c d e]

2.8 map

map 相当于 Python 中的字典,是以键值对进行存储的数据结构。

// 创建map有多种方式,基本格式为map[键的类型]值的类型

// 方式1
m := make(map[string]int)
m["one"] = 1
m["two"] = 2

// 方式2
m := map[string]int{"one": 1, "two": 2}

// 方式3
var m = map[string]int{"one": 1, "two": 2}

// 按键删除
delet(m, "one")

// 按键取值
fmt.Println(m["one"]) // 1

// 若不存在map中
r, ok := m["three"]
fmt.Println(r, ok) // 0, false

2.9 range

在 Go 语言中我们可以使用 range 来遍历 slice 或者 map

nums := []int{1, 2, 3}
for i, num := range nums {
    fmt.Println("index: ", i, "num: ", num)
}

如果我们不需要使用 index 的值,可以用 _ 占位,但如果用其它变量名却为使用改变量的话在编译时会出错。

for _, num := range nums {
    fmt.Println("num: ", num)
}

2.10 函数

在 Go 语言中,函数与变量一致,都是后置类型,并且可以返回多个值。

// 以func开头定义函数
func calculate(a int, b int) int {
    return a + b, a - b
}

func main() {
    sum, sub := calculate(5, 3)
    fmt.Println(sum, sub) // 8 2
}