Go基础语言|青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
1. 开发环境
go语言特点
- 高性能、高并发
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
1.1 安装Golang
1.2 选择集成开发环境
- vscode(需要安装go插件)
- goland
2. 基础语法
1.学习一门语言第一个程序输出helloworld
1. package
声明该文件所属的包,package main 程序的入口包
2. import
导入包
import(
"fmt"
)
导入标准库"fmt"包,输入输出格式化字符串
3. func main()
main函数
func mian(){
fmt.Println("hello world")
}
主函数,输出hello world
4.编译执行命令
- go run执行.go文件
- go build编译成二进制
2. 变量
func main() {
var a = "initial"
var b, c int = 1, 2
var d = true
var e float64
f := float32(e)
g := a + "foo"
}
go的string是内置类型,可用加号连接用等号比较,var 变量名=变量值 或 变量名:=变量值
3. 判断
if后面没有括号,if后面接大括号,语句从下一行起
if 7%2==0{
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
4. 循环
for{
//死循环
}
for i:=0;i<9;i++{
//和C一样
}
i:=0
for i<=3{
i=i+1
}
5. switch
a:=2//a可以是任何类型
switch a{
case 1:
//不需要写break
case 2:
//
default:
//其他情况
}
6. 数组
var a [5]int
a[4] = 100
b := [5]int{1, 2, 3, 4, 5}
var twoD [2][3]int
fmt.Println("get:", a[2])
fmt.Println("len:", len(a))
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
较少使用,主要使用切片
7. 切片
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
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]
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]
切片可以理解为可变长度的数组,可以更改长度,使用make创建切片,可用append追加元素,返回新的切片,可以访问任意位置,任意区间内的元素
8. map
m:=make(map[string]int)
m["one"]=1
r,ok:=m["pow"]
m2 := map[string]int{"one": 1, "two": 2}
map完全无序,遍历及不按照字母顺序,也不按照插入顺序,delete(m,"one)删除该组元素
9. range
可快速遍历 slice或map
- 遍历slice时返回两个值,第一个值是索引,第二个值是该索引位置上的值
- 遍历map时候,返回的第一个值是key(键),第二个值是该键对应的值.
for i, num := range nums {
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num) // index: 0 num: 2
}
}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
for k := range m {
fmt.Println("key", k) // key a; key b
}
10. 函数
golang函数支持返回多个值,参数类型后置,一般情况下,函数返回值中会有一个"错误"的返回值,判断该函数执行是否存在错误。
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
11. 指针
指针的主要用途是对传入的参数进行修改
func add2(n int) {
n += 2
}
func add2ptr(n *int) {
*n += 2
}
func main() {
n := 5
add2(n)
fmt.Println(n) // 5
add2ptr(&n)
fmt.Println(n) // 7
}
12. 结构体
带字段的集合,结构体作为参数的时候可以传指针,可以避免较大结构体在传参时进行拷贝的开销
package main
import "fmt"
type user struct {
name string
password string
}
func main() {
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}
c := user{name: "wang"}
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
fmt.Println(a, b, c, d) // {wang 1024} {wang 1024} {wang 1024} {wang 1024}
fmt.Println(checkPassword(a, "haha")) // false
fmt.Println(checkPassword2(&a, "haha")) // false
}
func checkPassword(u user, password string) bool {
return u.password == password
}
func checkPassword2(u *user, password string) bool {
return u.password == password
}
结构体函数,类似成员函数,*把func改为func (u user)或func (u user) ,传指针可对结构体进行修改
13. 错误处理
使用单独返回值进行错误信息,能很清晰知道哪里出现了错误,并且使用if else进行错误处理,在函数返回值类型加error类型,表示该函数会返回一个错误类型,如果出现错误,返回原本结果和错误信息,如果没有出现错误可返回原本结果和nil值,表示错误为空,也就是没有错误。在接收返回值有错误信息的函数时,需要用一个变量来单独接受错误信息,如果该变量不为空,则需进行错误处理,如果不需要错误信息可用下划线_来表示忽略错误信息的接收
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
x, _ := findUser([]user{{"wang", "1024"}}, "wang")
}
14. 字符串操作
a := "hello"
fmt.Println(strings.Contains(a, "ll")) // true
fmt.Println(strings.Count(a, "l")) // 2
fmt.Println(strings.HasPrefix(a, "he")) // true
fmt.Println(strings.HasSuffix(a, "llo")) // true
fmt.Println(strings.Index(a, "ll")) // 2
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
fmt.Println(strings.Repeat(a, 2)) // hellohello
fmt.Println(strings.Replace(a, "e", "E", -1)) // hEllo
fmt.Println(strings.Split("a-b-c", "-")) // [a b c]
fmt.Println(strings.ToLower(a)) // hello
fmt.Println(strings.ToUpper(a)) // HELLO
fmt.Println(len(a)) // 5
b := "你好"
fmt.Println(len(b)) // 6
15. 字符串格式化
- %v任意格式都可以打印出来
- %+v字段名称和值
- %#v类型名称字段名称和值
16. JSON处理
已有一个结构体
- 字段首字母大写
- 字段类型后加
json:"age"可将json序列化后的字段名修改为小写age - json.Marshal() 序列化结构体为十六进制编码(用string()强制转换即可)
- json.Unmarshal(序列化后的十六进制,空结构体变量) 反序列化
17. 时间处理
- time.Now()快速获取当前时间,具体操作见代码
- time.Date根据时区构造时间对象
- t.Sub(t1)求时间差
- t.Format("2006-01-02 15:04:05")解析时间格式
- t.Unix()获取时间戳
18. 字符串和数字之间转换
返回值有两个,一个为结果,一个为错误信息
- strconv.ParseInt("字符串",“进制/0是自动推测”,64)//64位整数
- strconv.Atoi("123")//快速将十进制字符串转换为数字
19. golang进程信息
- os.Args获取运行时参数
- os.Getenv("PATH")获取环境变量
- os.Setenv("AA","BB")写入环境变量
- exec.Command("grep","127.0.0.1","/etc/hosts").CombinedOutput()快速启动子进程并且获取输入输出