这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
01. Go语言
1.1 什么是go语言
- 高性能,高并发
- 语法简单,学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
02. Goland简单配置
Goland运行代码时生成的exe文件输出到了C盘下,这对于C盘空间不足的肯定是不想看见的,小编为大家提供了解决方案
解决方案
2.1 单个project生效
- 点击run->Edit Configurations...对exe文件的输出目录进行配置,配置后仅对当前project生效
2.2 全局修改
- 点击run->Edit Configurations...->Edit configuration templates...->在模板中对exe文件的输出目录进行配置,配置后全局生效
03. 入门程序-hello word
import "fmt"
func main() {
fmt.Println("hello world")
}
04. Go基础语法速通
4.1 基础语法-变量与常量声明
| Go数据类型 | |
|---|---|
| 布尔值 | 布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true |
| 数字类型 | 整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码 |
| 字符串类型 | 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本 |
| 派生类型 | 指针类型(Pointer)、数组类型、结构化类型(struct)、Channel 类型、函数类型、切片类型、接口类型(interface)、Map 类型 |
变量声明
- 方式一:指定变量类型
- 方式二:根据值自行判定变量类型
- 方式三:使用:=声明变量
var a string = "ABC"
var b = 1
c := 2
常量声明
- 方式一:指定常量类型
- 方式二:根据值自行判定常量类型
const d string = "sdf"
const e = 1
4.2 基础语法 - if else
if后面没有括号,如果编写在保存时,编译器启动去掉; if后面必须接大括号
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
4.3 基础语法 - for循环
go中只有一种for循环,可使用break跳出循环或continue继续循环
// 死循环
for {
fmt.Println("loop")
break
}
//经典循环
for j := 7; j < 9; j++ {
fmt.Println(j)
}
4.4 基础语法 - switch
switch在执行符合条件的case语句后跳出switch语句,无需在case后加break;
switch后可以加任意类型的变量,也可以不加变量,在case中写分支
a := 2
// 经典switch
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")
}
// 在case中进行条件判断
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
4.5 基础语法 - 数组
数组声明方式
定义数组: var a [5]int定义数组并初始化: b := [5]int{1, 2, 3, 4, 5}
4.6 基础语法 - 切片
切片是一种可变长度的动态数组,可以向数组一样使用,使用make函数快速创建切片,使用append来追加元素,必须将append的结果赋值给原数组
// 声明方式
s := make([]string, 3)
// 赋值
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2]) // c
fmt.Println("len:", len(s)) // 3
// append,并赋值到原数组【添加单个元素】
s = append(s, "d")
// append,并赋值到原数组【添加多个元素】
s = append(s, "e", "f")
fmt.Println(s) // [a b c d e f]
c := make([]string, len(s))
// slice复制
copy(c, s)
fmt.Println(c) // [a b c d e f]
// 取出第二位到第五位的元素,但不包含第五位的元素
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]
4.7 基础语法 - map
Go语言中的 map 是一种无序的键值对的集合,使用make函数快速创建map,并通过 key 来快速检索数据
// 定义一个map,key: string, value: int【未初始化】
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(len(m)) // 2
fmt.Println(m["one"]) // 1
fmt.Println(m["unknow"]) // 0
// r:value的值, ok:是否在map中检索到key
r, ok := m["unknow"]
fmt.Println(r, ok) // 0 false
// 删除map的一个键值对
delete(m, "one")
4.8 基础语法 - range
Go语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对
// 经典写法 i: key, v: value
for i, v := range nums {}
// 忽略值
for i, _ := range nums {}
// 忽略键
for _, v := range nums {}
4.9 基础语法 - 函数
Go 语言函数定义格式
func function_name( [parameter list] ) [return_types] {
函数体
}
- func:函数由 func 开始声明
- function_name:函数名称
- parameter list:参数列表,参数是可选的
- return_types:返回类型,可以有多个
- 函数体:函数定义的代码集合
4.10 基础语法 - 指针
一个指针变量指向了一个值的内存地址,在指针变量前面加上 * 号(前缀)来获取变量值,在指针变量前面加上 & 号(前缀)来获取变量地址
func add2ptr(n *int) {
*n += 2
}
func main() {
add2ptr(&n)
fmt.Println(n) // 7
}
4.11 基础语法 - 结构体
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合,使用指针对结果体的值进行修改
// 结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。name设定了结构体的名称
type name struct {
member definition
member definition
...
member definition
}
4.12 基础语法 - 结构体方法
类似java中的成员函数,修改结构体中字段的值需要使用指针
type user struct {
name string
password string
}
// 无法对结构体中password值进行修改
func (u user) checkPassword(password string) bool {
return u.password == password
}
// 可以对结构体中password值进行修改
func (u *user) resetPassword(password string) {
u.password = password
}
4.13 基础语法 - 错误处理
Go 语言通过内置的错误接口提供了非常简单的错误处理机制,在函数的返回类型值中加入error即实现错误处理,在实现函数时,必须返回error的值
// 示例函数
func findUser(users []user2, name string) (v *user2, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
4.14 基础语法 - 字符串操作与格式化输出
Go的string库内置多种字符串工具函数,在输出字符串时,使用%v来打印,无需区分字符串,%+v打印更详细的结果,%#v打印最详细的结果
4.15 基础语法 - JSON处理
对于一个结构体,保证成员变量首字母大学,即可通过json.Marshal去序列化结构体,序列化后的字符串可以通过json.Unmarshal去反序列化,在进行序列化时,可以通过json tag 修改JSON里的字段名
4.16 基础语法 - 时间处理
// 获取当前时间
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
// "2006-01-02 15:04:05" 默认格式化日期
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
4.17 基础语法 - 字符串转数字解析
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n) // 111
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) // 4096
n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
4.18 基础语法 - 进程信息
// go run example/20-env/main.go a b c d
fmt.Println(os.Args) // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
fmt.Println(os.Setenv("AA", "BB"))
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf)) // 127.0.0.1 localhost
05. 总结
首次学习Go语言略显生疏,后面会对本文进行改进,欢迎各位可以在评论区批评指正
参考
- Go 语言教程 | 菜鸟教程 (runoob.com)
- 字节跳动青训营GO原理基础课程