这是我参与「第五届青训营 」笔记创作活动的第1天
1.本堂课重点内容
- 介绍了go语言的特性
- go语言基础语法及标准库
2.具体案例
3.go语言的特性
- 高性能、高并发
- 语法简单、学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
4.go语言基础语法及标准库
4.1 变量&常量
var name = value //自动推导变量类型
var name type = value //自己定义类型
name := value //声名并且赋值 会自动推导变量类型
const name = value //常量的定义 无确定类型,根据上下文自动确定类型
const name type = value
4.2 判断语句
go语言中if的用法和c/c++/java都很类似,只是if后面不用加括号,但是if语句必须跟大括号,不能像c/c++/java一样省略。
if bool {
语句
} else {
语句
}
//特殊写法
//通过变量得到一个value值然后再根据变量值进行判断
if name := value; name != nill {
语句
}
4.3 循环语句
没有while循环和do while循环只有唯一的for循环 并且省略了for循环的括号
//死循环 类比 while(true)
for {
语句
}
//类比while条件判断循环
for i <= 3 {
语句
}
// 类比c的for循环 将初始化变量 int n = 0 变为 n := 0 省略括号
for n := 0 ; n < 5 ; n ++ {
语句
}
4.4 switch语句
switch后面不需要括号, 并且不需要break, 像c/c++/java;结束一个case语句都需要break,防止往下走。在switch后可以不加条件,直接case判断
switch 变量 {
case 1:
语句
case 2:
语句
default:
语句
}
//特殊用法 可以用作多个if判断
switch {
case bool:
语句
case bool:
语句
default:
语句
}
4.5 数组
var name [len]type //数组的定义
name := [len]type{...} //初始化
var name [len][len]type //二维数组的定义
4.6 切片
切片就是一个可变长度的数组
name := make([]type, len) //切片的定义
name[0] = value //赋值
name = append(name, value) //追加元素
copy(name1, name) //把name复制给name1
name[begin:end] // 切片操作
name[begin:]
name[:end]
4.7 map
name := make(map[key type]value type)
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
len(m) 获取 map 的长度
delete(m, key) //删除指定键值对
4.8 range
nums := []int{2, 3, 4}
//遍历数组 i代表下标, num代表值
for i, num := range nums {
语句
}
如果不需要下标或者值可以用_标识如
for i, _ := rangs nums{
语句
}
m := map[string]string{"a":"A", "b":"B"}
k为键,v为值
for k, v := range m {
语句
}
4.9 函数
与c/c++/java 不一样的是可以返回多个值,类型后置
//go函数的定义 type1是传入参数的类型 type2为返回值类型
func name(value type1) type2 {
语句
}
//多返回值
func name(value type1) (name type, name type){
语句
}
4.10 指针
//这个方法并不会改变n的值
func add2(n int){
n += 2
}
//这个方法会改变n的值 使用时 add2ptr(&n)
func add2ptr(n *int){
*n += 2
}
4.11 结构体
结构体是带类型字段的集合
//结构体的定义
type name struct{
//名称 类型
name1 type
name2 type
}
//使用
a := name{name1:".", name2:".."} //初始化
a.name1 = "xxx"
var d name //变量的声名
4.12 结构体方法
类似其他语言的类成员函数
type user struct {
name string
password string
}
//结构体方法
func (u user) checkPassword(password string) bool {
return u.password == password
}
//指针形式
func (u *user) resetPassword(password string) {
u.password = password
}
4.13 错误处理
使用一个单独的返回值来传递错误信息,可以很清晰的知道哪个函数返回了错误
func name(value type) (value type, err error){
语句
return value, errors.New("错误") //没有错误可以返回nil
}
4.14 字符串操作
a := hello
strings.Contains(a, "ll") //字符串中是否包含某个子串
strings.Count(a, "l") //计算某个字符串出现的次数
fmt.Println(strings.HasPrefix(a, "he")) //是否有前缀“he”
fmt.Println(strings.HasSuffix(a, "llo")) //是否有后缀“llo”
fmt.Println(strings.Index(a, "ll")) //查找某个字符串出现的位置
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) //连接多个字符串变为 he-llo
fmt.Println(strings.Repeat(a, 2)) //重复某个字符串多少次
fmt.Println(strings.Replace(a, "e", "E", -1)) //替换字符e为E
fmt.Println(strings.Split("a-b-c", "-")) //切割a-b-c把-切掉
fmt.Println(strings.ToLower(a)) //全变小写
fmt.Println(strings.ToUpper(a)) //全变大写
4.15 字符串格式化
fmt.printf 类似c printf
%v //可以打印任意类型
%+v //得到更详细的结果
%#v //进一步详细
4.16 JSON处理
//把一个结构体转换为一个json格式
json, err = json.Marshal(结构体)
//使用unmarshal可以返序列化到一个结构体
json.Unmarshal(json, &结构体)
4.17 时间处理
主要使用的是time类
// 获取当前时间
now := time.Now()
// 构造一个带时区的时间
t := time.Date(年, 月, 日, 时, 分, 秒, 纳秒, 时区)
t.Year 获取年
t.Month 获取月
t.Day 获取日
t.Hour 获取时
t.Minute 获取分
//时间戳
now.Unix
4.18 数字解析
主要使用strconv库
//把字符串转换为64位精度的浮点数
strconv.ParseFloat("1.234", 64)
//把字符串转换成10进制64位精度的整数
strconv.ParseInt("111", 10, 64)
//使用atoi快速把字符串转成10进制数字
strconv.Atoi("123")
4.19 进程信息
os.Args //获取运行时的参数 如go run main.go a, b, c, d 第一个参数为二进制自身的目录加名字 剩下的则为 a, b, c, d
//获取或写入环境变量
os.Getenv("PATH")
os.Setenv("AA", "BB")
//快速启动子进程并获取其输入输出
exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()