青训营后端笔记1-Go 语言的基础语法和常用特性解析 | 豆包MarsCode AI刷题

84 阅读7分钟

第一节课:Go语言的原理和实践,用短短的数小时时间搭建了Go语言的开发环境,熟悉了Go语言的基本语法,了解了Go语言的标准库,并通过编写简单的猜谜游戏、命令行字典、sock5代理等程序,帮助我快速入门了Go语言。

首先,什么是Go语言?Go语言有哪些特点?

Go 语言(简称 Golang)是 Google 开发的一种开源编程语言,以简洁、高效、并发和安全著称。

1.高性能、高并发

Go语言拥有和C++、Java媲美的性能,同时支持高并发,不需要像其他语言去寻找高度优化的第三方库来开发,只需要使用自带的标准库和以标准库为基础的第三方库,即可开发高并发的应用程序

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

Go语言的语法风格类似于C语言,在C语言的基础上还进行了大幅度的简化,例如去掉了不需要的表达式括号、循环的表示方法只有for循环一种等,只需要简单的语法就可以实现数值、键值等的各种遍历,学习起来简单易懂。熟练的开发者只需要一周就能从Go语言的学习阶段转到开发阶段,编写出高性能高并发的应用程序。

3.丰富的标准库

Go语言和Python一样,拥有极其丰富、功能完善、质量可靠的标准库,在很多情况下不需要借助第三方库,只需要标准库就可以完成大部分基础功能的开发,这大大降低了学习和使用成本。最关键的是,标准库有很高的兼容性和稳定性保障,还能享受语言迭代带来的性能优化。

4.完善的工具链

Go语言提供从编译、代码格式化、错误检测、帮助文档、包管理、代码补充提示等一体化工具链,简化开发流程,还内置了单元测试框架,能进行单元测试,性能测试,代码覆盖率等,这些都是保证代码能正确和稳定运行的必备利器。

5.静态链接

通过静态链接将所有依赖编译到一个独立的可执行文件中,使程序具有极高的独立性,便于部署和运行环境的管理。在线上的容器环境下运行,体积可以控制地非常小,部署非常方便快捷。

6.快速编译

Go语言的模块化设计、单一编译单元和并行编译机制,显著加快了代码编译速度,即使是大型项目也能在几秒内完成构建。

7.跨平台

Go语言提供内置的跨平台支持,可以在Linux、Windows、MacOS等常见操作系统下运行,也能够用来开发Android、ios软件,通过简单的配置即可生成适配不同操作系统和架构的独立可执行文件,极大地提高了项目的适配性。Go语言还有很方便的交叉编译特性,它可以在你的笔记本电脑上轻易编译出一个二进制文件,然后拷贝到路由器上运行,还无需配置交叉编译环境。

8.垃圾回收

Go语言的并发垃圾回收器能够高效管理内存,减少开发者手动管理内存的负担,并优化暂停时间,适合对性能和实时性要求高的应用,可以让开发者更专注于业务逻辑。

简单了解Go语言后,我们开始开发环境的搭建:

1.下载并安装Golang

下载地址:Go下载 - Go语言中文网 - Golang中文社区

2.使用VScode作为Golang集成开发环境

VScode下载地址:Visual Studio Code - Code Editing. Redefined

3.配置环境变量

参考:VScode下配置Go语言开发环境【2023最新】_vscode go-CSDN博客

安装好了环境后,我们就可以熟悉一下golang的各种语法:

首先是最简单的Hello World,package名为main,import导入fmt包,使用Println()来打印内容,每行末尾不需要冒号。

package main

import (
	"fmt"
)

func main() {
	fmt.Println("hello world")
}

变量语法,var有多种方式来声明变量,:=可以声明变量的同时进行初始化,golang中常量具有高精度和任意范围,且不受变量类型限制。

package main

import (
	"fmt"
	"math"
)

func main() {

	var a = "initial"

	var b, c int = 1, 2

	var d = true

	var e float64//未初始化时默认值为 `0`

	f := float32(e)//将 `e` 从 `float64` 转为 `float32`

	g := a + "foo"//字符串拼接
	fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
	fmt.Println(g)                // initialapple
 
	const s string = "constant"
	const h = 500000000
	const i = 3e20 / h//不受变量类型限制
	fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
  //constant 500000000 6e+11 -0.28470407323754404 0.9773549496199987
}

for语法,for {} 表示一个无限循环,没有任何条件限制,条件不需要括号。条件中仅有判断的循环形式类似于 while,如for i <= 3 { fmt.Println(i) i = i + 1 }

package main

import "fmt"

func main() {

	i := 1
	for {
		fmt.Println("loop")
		break
	}
	for j := 7; j < 9; j++ {
		fmt.Println(j)
	}

	for n := 0; n < 5; n++ {
		if n%2 == 0 {
			continue
		}
		fmt.Println(n)
	}
	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
}

if语法,条件同样不需要括号,:=表示声明并初始化了变量 num,需要注意的是不论if后跟多少条语句,即使只有一条语句也必须用{}包裹起来。

package main

import "fmt"

func main() {

	if 7%2 == 0 {
		fmt.Println("7 is even")
	} else {
		fmt.Println("7 is odd")
	}

	if 8%4 == 0 {
		fmt.Println("8 is divisible by 4")
	}

	if num := 9; num < 0 {
		fmt.Println(num, "is negative")
	} else if num < 10 {
		fmt.Println(num, "has 1 digit")
	} else {
		fmt.Println(num, "has multiple digits")
	}
}

switch语法,不需要像 C/C++ 那样写 break,匹配到条件后会自动退出分支,不会继续执行后续的分支。并且支持多个值匹配一个分支,例如 case 4, 5:

package main

import (
	"fmt"
	"time"
)

func main() {

	a := 2
	switch a {
	case 1:
		fmt.Println("one")
	case 2:
		fmt.Println("two")
	case 3:
		fmt.Println("three")
	case 4, 5:
		fmt.Println("four or five")
	default:
		fmt.Println("other")
	}

	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("It's before noon")
	default:
		fmt.Println("It's after noon")
	}
}

数组语法,Go 的数组是固定长度的,长度在声明时确定,无法动态调整。如果需要动态数组,可以使用切片slice。声明数组后,未赋值的元素会自动初始化为对应类型的零值(整数为 0,布尔值为 false,字符串为 "")。使用 len 获取数组长度,无需显式定义。golang也支持多维数组,且可以通过嵌套循环初始化每个元素,操作方法与一维数组类似。

package main

import "fmt"

func main() {

	var a [5]int
	a[4] = 100
	fmt.Println("get:", a[2])
	fmt.Println("len:", len(a))

	b := [5]int{1, 2, 3, 4, 5}
	fmt.Println(b)

	var twoD [2][3]int
	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			twoD[i][j] = i + j
		}
	}
	fmt.Println("2d: ", twoD)
}

slice切片语法,使用 make 创建切片,切片元素通过索引直接赋值(如 s[0] = "a")。append 用于向切片添加元素,会在需要时动态扩展切片容量,多个元素可以一次性追加。使用 copy 将一个切片的内容复制到另一个切片。

package main

import "fmt"

func main() {

	s := make([]string, 3)//切片长度为 `3`,元素类型为 `string`。
	s[0] = "a"//通过索引直接赋值
	s[1] = "b"
	s[2] = "c"
	fmt.Println("get:", s[2])   // c
	fmt.Println("len:", len(s)) // 3

	s = append(s, "d")//向切片添加元素
	s = append(s, "e", "f")
	fmt.Println(s) // [a b c d e f]

	c := make([]string, len(s))
	copy(c, s)//复制切片
	fmt.Println(c) // [a b c d e f]
   //使用类似python的语法获取切片的切片
	fmt.Println(s[2:5]) // [c d e]
	fmt.Println(s[:5])  // [a b c d e]
	fmt.Println(s[2:])  // [c d e f]

	good := []string{"g", "o", "o", "d"}
	fmt.Println(good) // [g o o d]
}

另有map,func,range,time,struct,error,string,json等丰富的语法内容,由于篇幅关系,就不再讲解,更多内容将在下一篇笔记中学习和记录。