day1后端与Go语言基础 | 青训营笔记

95 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天。

主要是学习了基础语法,敲了遍代码;实战案例的作业还没完成,在接下来的学习中会补上。

一、本堂课重点内容:

  • Go语言基础语法
  • Go语言实战案例
    • 猜谜游戏
    • 在线词典
    • Socks5代理

二、Go语言基础语法:

1. 特点

高性能、高并发;丰富标准库、工具链;静态链接、快速编译、跨平台;垃圾回收(无需考虑内存分配释放)。

2. 开发环境

a. 安装Golang:go.dev/

b. 配置集成开发环境:VS Code、GoLand;

3. 基础语法

a. Hello World

package main //main包的一部分,程序的入口包,入口文件
import (
    "fmt" //导入fmt包,往屏幕输入输出字符串、格式化字符串
)
func main() {
    fmt.Println("Hello World") //主函数,打印
}

b. 变量与常量

package main
import (
    "fmt"
    "math"
)
func main() {
    //定义、赋值 -- 有确定类型
    var a = "initial"
    var b, c int = 1, 2
    var d = true
    var e float64
    f := float32(e)
    g := a + "go" //string是内置类型,可直接用“+”拼接
    fmt.Println(a, b, c, d, e, f)
    fmt.Println(g)
    //常量 -- 无确定类型
    const s string = "constant"
    const h = 50000000
    const i = 3e20 / h
    fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}

c. if else

package main
import "fmt" //只用一个,可以不加括号
func main() {
    var num int = 7
    if num%2 == 0 {
        fmt.Println(num, "is even.")
    } else if num := 10; num <0 { //可以在if里面定义变量
        fmt.Println(num, "is negative.")
    } else {
        fmt.Println(num, "is not less than 0.")
    }
}

d. for(go语言只有一种循环)

package main
import "fmt"
func main() {
    i := 1
    for { // 死循环
        fmt.Println("loop")
        break
    }
    for i <= 3 {
        fmt.Println("i")
        i = i + 1
    }
    for j := 7; j<9; j++ {
        fmt.Println("j")
    }
}

e. switch(go语言的用法更灵活)

package main
import (
    "fmt"
    "time"
)
func main() {
    a := 2
    switch a {
    case 1: 
        fmt.Println("one")
    case 2:
        fmt.Println("two")
    default:
        fmt.Println("other")
    }
    //或者当作if else来用
    t := time.Now()
    switch {
    case t.Hour() < 12:
        fmt.Println("It's moring.")
    default:
        fmt.Println("It's afternoon.")
    }
}

f. 数组(不常用,长度不可变)

package main
import "fmt"
func main() {
    var a [5]int
    a[4] = 100
    fmt.Println(a[4], 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++ {
            towD[i][j] = i+j
        }
    }
    fmt.Println("2d: ", twoD)
}

g. 切片slice(可变长度数组)

package main
import "fmt"
func main() {
    //初始化
    s := make([]string, 3)
    //赋值
    s[0] = "a"
    s[1] = "b"
    s[2] = "c"
    fmt.Println("get:", s[2])
    fmt.Println("len:", len(s))
    //使用append在末尾添加
    s = append(s, "d")
    s = append(s, "e", "f")
    fmt.Println(s)
    //使用copy拷贝
    c := make([]string, len(s))
    copy(c, s)
    fmt.Println(c)
    //切片打印
    fmt.Println(s[2:5])
    fmt.Println(s[:5])
    fmt.Println(s[2:])
    //直接赋值初始化
    g := []string{"g", "o"}
    fmt.Println(g)
}

h. map

package main
import "fmt"
func main() {
    //初始化make(map[key类型]value类型)
    m := make(map[string]int)
    m["one"] = 1
    m["two"] = 2
    fmt.Println(m)
    fmt.Println(len(m))
    fmt.Println(m["one"])
    //打印不存在的键值
    fmt.Println(m["unknow"]) //默认为0
    r, ok := m["unknow"]
    fmt.Println(r, ok) //0 false
    //删除某个键值对
    delete(m, "one")
    //直接赋值初始化
    m2 := map[strig]int{"one": 1, "two": 2}
    var m3 = map[strig]int{"one": 1, "two": 2}
    fmt.Println(m2, m3)
}

i. range

package main
import "fmt"
func main() {
    nums := []int{2, 3, 4}
    sum := 0
    //循环数组里面的元素
    for i, num := range nums {
        sum += num
        if num == 2 {
            fm.Println("index:", i, "num:", num)
        }
    }
    fmt.Println(sum)
    
    m := map[strig]string{"a": A, "b": B}
    for k, v := range m {
        fmt.Println(k, v)
    }
    for k := range m {
        fmt.Println("key", k)
    }
}

j. 函数

package main
import "fmt"
//关键字func 函数名add 变量a 变量类型int 函数返回类型int
func add(a int, b int) int {
    return a + b //函数返回
}
//也可以不定义变量类型
func add2(a, b int) int {
    return a + b
}
//多个函数返回,外面加括号,里面逗号隔开
func exists(m map[strig]string, k string) (v sring, ok bool) {
    v, ok = m[k]
    return v, ok
}
func main() {
    res := add(1, 2)
    fmt.Println(res)
    
    v, ok := exists(map[strig]string{"a": A}, "a")
    fmt.Println(v, ok)
}

k. 指针

package main
import "fmt"
//不会改变main中传入变量的值
func add2(n int) {
    n += 2
}
//会改变main中传入变量的值
func add2ptr(n *int) {
    *n += 2 //使用时加个*
}

func main() {
    n := 5
    add2(n)
    fmt.Println(n)
    add2ptr(&n) //使用时加个&
    fmt.Println(n)
}

l. 结构体

package main
import "fmt"

type user struct {
    name string
    password string
}

func main() {
    a := user{name: "wang", password: "1234"}
    b := user{"wang", "1234"}
    c := user{name: "wang"}
    var d user
    d.name = "wang"
    d.password = "1234"
    fmt.Println(a, b, c, d)
    
    fmt.Println(checkPassword(a, "1024"))
    fmt.Println(checkPassword2(&a, "1024"))
}

func checkPassword(u user, password string) bool {
    return u.password == password
}

func checkPassword2(u *user, password string) bool {
    return u.password == password
    //这里u前面不用加*吗?
}

m. 结构体方法

package main
import "fmt"

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
    //这里u前面不用加*吗?
}

func main() {
    a := user{name: "wang", password: "1234"}
    a.resetPassword("1024")
    fmt.Println(a.checkPassword("1024"))
}

n. 错误处理

package main
import "fmt"
func main() {
    
    fmt.Println()
}

o. 字符串操作

package main
import "fmt"
func main() {
    
    fmt.Println()
}

一个中文字符占3个长度

p. 格式化打印

package main
import "fmt"
func main() {
    
    fmt.Println()
}

q. json处理

package main
import "fmt"
func main() {
    
    fmt.Println()
}

Key的第一个字母大写

Marshal(a)序列化

Unmarshal反序列化

r. 时间处理

package main
import "fmt"
func main() {
    
    fmt.Println()
}

Unix 时间戳

s. 数字解析

package main
import "fmt"
func main() {
    
    fmt.Println()
}

import "strconv"

t. 进程信息

package main
import "fmt"
func main() {
    
    fmt.Println()
}

os

os/exec

三、Go语言实战案例:

1. 猜谜游戏

a. 生成随机数

math/rand

每次随机都是数字相同?

解决:rand.Seed(time.Now.UnixNano())

b. 用户输入输出

输入bufio--去换行符--转为整数

或者scanf也可以

c. 用户多次猜测

for

2. 在线词典

彩云小译api

fanyi.caiyunapp.com/

代码生成curl

curlconverter.com/#go (删去编译不成功的行)

代码解读

运行生成一串json

序列化json

代码生成response body

oktools.net/json2go 转换-嵌套

打印需要的对应字符段

功能基本实现--完善代码

3. Socks5代理

a. tcp sever

go process 子线程

defer 要结束这个连接

b. auth认证

c. connect请求阶段

d. relay阶段

四、作业&课后个人总结:

  1. 第一个例子,fmt.Scanf简化代码实现

  2. 第二个例子,增加另一个翻译引擎

  3. 第二个例子,作业2的基础上,实现并向请求两个翻译引擎

五、引用参考:

标题:走进 Go 语言基础语言 - 掘金

网址:juejin.cn/course/byte…

标题:Go 语言的实战案例 - 掘金

网址:juejin.cn/course/byte…