这是我参与「第五届青训营」伴学笔记创作活动的第 1 天
前言
本人目前研二,常用Python。在做本科毕设时用过一段时间的Go。这次借着参加青训营的机会重新学习一遍Go语言。
Go语言简介
Go是一种由谷歌开发的,一种静态强类型,跨平台,支持高并发和垃圾回收的编译型语言。因其具有丰富的第三方库,支持快速编译,而被越来越多的开发者所青睐。
早期,go的编译器由C语言写成,后来官方用Go重写实现了自举。这也是目前为数不多的的实现了自举的一种编程语言。
截至目前(2023年1月15日),Go已经更新到了1.19版本。
基本准备
基本开发环境安装
在正式开发之前,需要先安装Go语言的编程环境。在Go官网(这个在国内访问会快)可以安装Go语言及其对相应的工具和库。安装完成后,使用go Version
命令验证安装是否成功。如果提示找不到命令,请将安装目录下的bin目录添加到环境变量。
为了更快的安装第三方包,需要使用以下命令
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct
此外,go语言的许多库需要使用cgo编译,因此建议同时安装gcc、g++。如果在linux或者wsl下,可以直接使用下面的命令安装。如果在windows下,请参考此文章安装,并设置环境变量。
# debian,ubuntu等debian衍生系统
sudo apt install gcc g++
# 其他系统请自行使用包管理命令安装
# 使用源码安装请参考安装文档
IDE选择
“工欲善其事,必先利其器”。选择一款合适的IDE可以极大的提高开发效率。目前,主流的IDE通常通常有VsCode,Goland,Eclipse等。Goland具有功能全面,操作简单等特点。对于新手小白或者像我一样的懒得折腾的人来说(不是),其无疑是最好的选择。而VsCode和Eclipse具有轻量化、可自定义等特点。对于具有丰富实践经历,喜爱折腾的人来说,选择Vscode或者Eclipse更好。
P.S. Gland是一款付费软件。但对于学生党来说,可以向Jetbrains申请免费的教育许可,有效期一年,过期后如果还是学生身份,可以再次申请。教育许可中其中包括了Jetbrains全家桶,总有一款适合你。(建议申请,白嫖的不香吗?)
开始开发
Hello World
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
如代码所示,以上便是使用Go语言在命令行中输出“Hello world!”的代码。在第一行,package 声明了此go文件所在的包。通常情况下,为文件所在的文件夹的名字。比如,有一个Go文件1.go在目录code01中,那么在1.go的开头需要写package code01
。然而,当文件中存在程序启动入口函数,如main
时,包名需要声明为main
,此处与实例一致
第二行代码声明了引用的库fmt
,这是一个基本库。此外,这里有一个知识点,当有多个包引入时,需要进行排序。
下面三行代码是函数主体。表明了函数的具体执行逻辑。使用fmt中的Println函数输入指定字符串。这里的函数名首字母大写表示这是一个可以被外部使用的函数。在 Go 语言中,函数/方法首字母大写意味着可被其他包调用,否则只能在该包被调用,这就类似于 python 中 function
和 __function
的区别。
变量
声明一个变量。下面是一个标准的声明变量的语句,包括变量名、类型和初始值。
var i int = 1
然而,由于Go语言支持类型推断,同时为了简化开发过程。一般不会将上述内容全部写出。而是结合情况只写一部分。
var i = 1 // 与标准语句等价
var j int // 声明变量j是整形,同时自动赋初值
k := 1 // 与标准语句等价
此外,还可以使用const
声明常量。
const DEFAULT_HOST = "127.0.0.1"
流程控制语句
Go语言仅支持 for, if-else if -else, switch 语句。其用法与C,java类似。这里不再介绍
部分变量
在Go中,切片和映射这两个变量比较特殊。切片比较类似于python中的list,而映射比较类似于dict。此外声明这两个变量的时候一般也不使用var语句,而是调用make函数。
// any 表示任意类型
s := make([]any,length,capacity)
m := make(map[any]any)
函数、结构体
函数
如下代码所示,声明一个函数。要注意函数名的首字母的大小写问题。在前文已经提过。此外,Go语言支持多值返回。
// 无返回值
func sayHello(name string) {
fmt.Println("hello," + name)
}
// 有返回值,返回ok
func sayHello(name string) string {
fmt.Println("hello," + name)
return "ok"
}
// 多值返回,返回一个int和一个string
func func1() (int,string) {}
结构体
与C语言中的结构体类似,使用type structName struct {}
声明,使用.
访问。
// 声明结构体
type user struct {
name string
gender string
}
u := user{name:"Mike"}
// 获取成员
fmt.Println(u.name) // mike
// 修改成员
u.name = "Leo"
fmt.Println(u.name) // Leo
此外,结构体支持结构体的嵌套和引用。
嵌套
type A struct {
b int
c int
}
type D struct {
a A
}
d := D {a:{b:1,c:2}}
// 访问
fmt.Println(d.a.b) // 1
// 引用
type A struct {
b int
c int
}
type D struct {
A
}
// 等价于
type D struct {
b int
c int
}
结构体方法
结构体方法可以大致看成类方法,根据函数名首字母的大小写视为public
或者private
方法。
type A struct {}
func (a A) func1() {}
func (a *A) func2() {}
// 声明
a := A{}
// 调用
a.func1()
a.func2()
标准库
与 Python 相同,Go 拥有一个非常强大的标准库,包含了字符串操作,字符串格式化,日期与时间处理,JSON 解析,数字解析,进程信息等功能。
值得一提的是,对于日期和时间处理,Go 使用 2006-01-02 15:04:05
来表达日期和时间模板,而不是传统的 yyyy-MM-dd HH:mm:ss
,据说写这个日期是为了方便用户记忆和使用。
实战
在这一部分,字节内部课:Go 语言上手 - 基础语法通过三个简单的小项目学习了 Go 语言语法及其标准库使用:一个经典的猜数字游戏;一个在线词典,通过调用在线词典的Api返回单词的意思;一个 SOCKS5 代理,简单的实现了 SOCKS 5 的握手流程,并给予回答。
参考
- 字节内部课:Go 语言上手 - 基础语法
- Go 语言教程 | 菜鸟教程 (runoob.com)