day03
函数
package main
import "fmt"
//导入包(标准包,自定义包,第三方包)
//包级别的变量,常量,函数
//无参 无返回值
func sayHello() {
fmt.Println("Hello World")
}
//有参 无返回值
func sayHi(name string, name2 string) {
fmt.Println("Hi", name, name2)
}
//有参 有返回值
func add(n1 int, n2 int) int {
return n1 + n2
}
func test(a int, b string) {
fmt.Println(a, b)
}
func main() {
//sayHello
//调用 方法名()
sayHello()
sayHi("aa", "bb")
n := add(1, 2)
fmt.Println(n)
test(1, "cc")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run func.go
Hello World
Hi aa bb
3
1 cc
*/
参数
参数合并
package main
import "fmt"
//参数类型合并
//连续多个变量类型相同
// 保留最后一个元素类型,前面的类型都可以省略
func add(n1, n2 int) int {
return n1 + n2
}
func test(p1, p2 string, p3, p4 int, p5, p6 bool) {
fmt.Printf("%T,%T,%T,%T,%T,%T\n", p1, p2, p3, p4, p5, p6)
fmt.Println(p1, p2, p3, p4, p5, p6)
}
func main() {
fmt.Println(add(1, 2))
test("", "", 0, 0, false, false)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run params.go
3
string,string,int,int,bool,bool
0 0 false false
*/
可变参数
package main
import "fmt"
//可变参数的函数
func test(args ...string) {
fmt.Printf("%T,%#v\n", args, args)
}
//1.可变参数 在一个方法中只能有一个
//2.并且可变参数必须放在函数声明参数列表最后
//举例(函数至少有n个参数)
//add(n1,n2,...)
func add(n1, n2 int, args ...int) int {
total := n1 + n2
for _, v := range args {
total += v
}
return total
}
func main() {
test()
test("1")
test("1", "2", "3")
fmt.Println(1, 2)
fmt.Println(1, 2, 3)
fmt.Println(1, 2, 3, 4)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run args.go
[]string,[]string(nil)
[]string,[]string{"1"}
[]string,[]string{"1", "2", "3"}
1 2
1 2 3
1 2 3 4
*/
解切片
package main
import "fmt"
//可变参数的函数
func test(args ...string) {
fmt.Printf("%T,%#v\n", args, args)
}
//1.可变参数 在一个方法中只能有一个
//2.并且可变参数必须放在函数声明参数列表最后
//举例(函数至少有n个参数)
//add(n1,n2,...)
func add(n1, n2 int, args ...int) int {
total := n1 + n2
for _, v := range args {
total += v
}
return total
}
func calc(n1, n2 int, args ...int) int {
//直接调用add把add方法结果进行返回
//args切片
// switch(len(args))
//add(n1,n2,args[0],args[1]...)
return add(n1, n2, args...) //解操作
}
func main() {
// test()
// test("1")
// test("1", "2", "3")
// fmt.Println(1, 2)
// fmt.Println(1, 2, 3)
// fmt.Println(1, 2, 3, 4)
params := []int{1, 2, 3, 4, 5, 6, 7}
fmt.Println(add(1, 2, params...))
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run args.go
31
*/
返回值
多返回值&命名返回值&合并返回值类型
package main
import "fmt"
func add(n1, n2 int) int {
return n1 + n2
}
func mult(n1, n2 int) int {
return n1 * n2
}
//多返回值
func calc(n1, n2 int) (int, int) {
//a,b:=1,2
r1 := add(n1, n2)
r2 := mult(n1, n2)
return r1, r2
}
//命名返回值
func calc2(n1, n2 int) (r1 int, r2 int) {
//a,b:=1,2
r1 = add(n1, n2)
r2 = mult(n1, n2)
return
}
//合并返回值类型
func calc3(n1, n2 int) (r1, r2 int) {
//a,b:=1,2
r1 = add(n1, n2)
r2 = mult(n1, n2)
return
}
func main() {
fmt.Println(calc(1, 2))
fmt.Println(calc2(1, 2))
fmt.Println(calc3(1, 2))
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run return.go
3 2
3 2
3 2
*/
值类型和引用类型
package main
import "fmt"
func main() {
//值类型 b=a
age := 30
tmpAge := age
tmpAge = 31
fmt.Println(age, tmpAge)
fmt.Printf("%p,%p\n", &age, &tmpAge)
//引用类型 b=a (地址)
users := make([]string, 10)
tmpUsers := users
tmpUsers[0] = "xx"
fmt.Printf("%#v,%#v\n", users, tmpUsers)
fmt.Printf("%p,%p\n", users, tmpUsers)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run quote.go
30 31
0xc0000aa058,0xc0000aa070
[]string{"xx", "", "", "", "", "", "", "", "", ""},[]string{"xx", "", "", "", "", "", "", "", "", ""}
0xc0000a2140,0xc0000a2140
*/
函数使用值类型和引用类型
package main
import "fmt"
func test1(n int) {
n = 1
}
func test2(s []int) {
fmt.Printf("test2:%p\n", s)
s[0] = 1
}
func main() {
a := 0
b := make([]int, 10)
test1(a)
test2(b)
fmt.Println(a)
fmt.Println(b)
fmt.Printf("main:%p\n", b)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run quote.go
test2:0xc0000b00f0
0
[1 0 0 0 0 0 0 0 0 0]
main:0xc0000b00f0
*/
根据条件,返回不同的返回值
package main
import "fmt"
func test(flag bool) int {
if flag {
return 1
}
fmt.Println("return before")
return 2
}
func main() {
fmt.Println(test(true))
fmt.Println(test(false))
}
递归
阶乘
package main
import "fmt"
//阶乘
//n!=
// n=0 n!=1
// n>=1 n!=n*(n-1)!=n*(n-1)*...*1
// f(n) = n!
// f(n) = n*f(n-1)
// 分治=> 大问题分解为多个相同的小问题(小问题可以继续拆分,直到某一个可以解决的子问题)
// 递归调用=>函数直接或间接调用自己(总有一个停止的条件,)
func f(n int64) int64 {
if n == 0 {
return 1
}
return n * f(n-1)
}
func main() {
//f(3)=3*f(2)=3*2*f(1)
fmt.Println(f(3))
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run fact.go
6
*/
汉诺塔
从start挪到end 接着temp
package main
import (
"fmt"
)
// n个盘子 start(开始) end(终点) temp(借助)
// n start -> temp ->end
// n -1 start ->end =>temp
// start ->end
// n-1 temp -> start ->end
// 终止条件 start -> end
func tower(start string, end string, temp string, layer int) {
if layer == 1 {
fmt.Println(start, "->", end)
return
}
tower(start, temp, end, layer-1)
fmt.Println(start, "->", end)
tower(temp, end, start, layer-1)
}
func main() {
tower("塔1", "塔3", "塔2", 3)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run tower.go
塔1 -> 塔3
塔1 -> 塔2
塔3 -> 塔2
塔1 -> 塔3
塔2 -> 塔1
塔2 -> 塔3
塔1 -> 塔3
*/
函数指针传递
package main
import "fmt"
//值类型 在函数内修改实参的值
//fmt.Scan(&age)
func change(value int) {
value += 1
}
func changePoint(pointer *int) {
*pointer = *pointer + 1
}
func main() {
value := 1
change(value)
fmt.Println(value)
changePoint(&value)
fmt.Println(value)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run pointer.go
1
2
*/
函数类型
package main
import "fmt"
// //无参 无返回值
// func sayHell() {
// fmt.Println("Hello World")
// }
// //有参 无返回值
// func sayHi(name string, name2 string) {
// fmt.Println("Hi:", name, name2)
// }
// //有参 有返回值
// func add(n1 int, n2 int) int {
// return n1 + n2
// }
func test(a int, b string) int {
fmt.Println(a, b)
return 1
}
func main() {
//test() //函数调用
a := test
b := test(1, "") //执行test函数 打印 1 "" //空字符省略了
fmt.Printf("%T\n", test)
fmt.Printf("%T\n", a)
fmt.Printf("%T\n", b)
a(1, "xx")
// callback的值是nil
var callback func(int, int) int
fmt.Printf("%T,%#v\n", callback, callback)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run type.go
1
func(int, string) int
func(int, string) int
int
1 xx
*/
声明函数类型&类型一致赋值
package main
import "fmt"
//有参 有返回值
func add(n1 int, n2 int) int {
return n1 + n2
}
func main() {
// callback的值是nil
var callback func(int, int) int
fmt.Printf("%T,%#v\n", callback, callback)
callback = add
fmt.Printf("%#v\n", callback)
rt := callback(1, 4)
fmt.Println(rt)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run type.go
func(int, int) int,(func(int, int) int)(nil)
(func(int, int) int)(0x76dd40)
5
*/
类型不一致不能赋值
必须一致才能赋值
//有参 有返回值
func add(n1 int, n2 int) int {
return n1 + n2
}
func test(a int, b string) int {
fmt.Println(a, b)
return 1
}
高阶函数
函数作为参数 funcparams.go
package main
import "fmt"
func calc(n1 int, n2 int, callback func(int, int) int) int {
//不定义什么运算
//通过函数参数传递要进行的运算
rt := callback(n1, n2)
//检查结果在0,100范围内,超过-1
if rt >= 0 && rt <= 100 {
return rt
}
return -1
}
func add(n1, n2 int) int {
return n1 + n2
}
func mult(n1, n2 int) int {
return n1 * n2
}
func main() {
rt := calc(1, 2, add)
fmt.Println(rt)
rt = calc(1, 2, mult)
fmt.Println(rt)
rt = calc(50, 30, add)
fmt.Println(rt)
rt = calc(50, 30, mult)
fmt.Println(rt)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run funcparams.go
3
2
80
-1
*/
匿名函数
匿名函数示例 lambda.go
示例1
package main
import "fmt"
func calc(n1 int, n2 int, callback func(int, int) int) int {
//不定义什么运算
//通过函数参数传递我要进行运算
rt := callback(n1, n2)
if rt >= 0 && rt <= 100 {
return rt
}
return -1
}
func main() {
add := func(n1, n2 int) int {
return n1 + n2
}
mult := func(n1, n2 int) int {
return n1 * n2
}
rt := calc(1, 2, add)
fmt.Println(rt)
rt = calc(1, 2, mult)
fmt.Println(rt)
rt = calc(50, 30, add)
fmt.Println(rt)
}
示例2 直接引入
package main
import "fmt"
func calc(n1 int, n2 int, callback func(int, int) int) int {
//不定义什么运算
//通过函数参数传递我要进行运算
rt := callback(n1, n2)
if rt >= 0 && rt <= 100 {
return rt
}
return -1
}
func main() {
// add := func(n1, n2 int) int {
// return n1 + n2
// }
// mult := func(n1, n2 int) int {
// return n1 * n2
// }
// rt := calc(1, 2, add)
// fmt.Println(rt)
// rt = calc(1, 2, mult)
// fmt.Println(rt)
// rt = calc(50, 30, add)
// fmt.Println(rt)
rt := calc(50, 30, func(n1, n2 int) int {
return n1 + n2
})
fmt.Println(rt)
rt = calc(50, 30, func(n1, n2 int) int {
return n1 * n2
})
fmt.Println(rt)
}
/*
D:\GoWork\src\go_course\day03-20230306>go run lambda.go
80
-1
*/
示例3 局部初始化
package main
import "fmt"
func main() {
func() {
fmt.Println("call")
}()
fmt.Println("1")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run lambda2.go
call
1
*/
匿名函数中作用域
函数fun(name string) 内没有声明desc 使用外部的,做修改了
示例1
package main
import "fmt"
func main() {
name, desc := "xx", "i'm xx"
func(name string) {
fmt.Println(name, desc)
}("aa")
fmt.Println(name)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run block.go
aa i'm xx
xx
*/
示例2
package main
import "fmt"
func main() {
name, desc := "xx", "i'm xx"
func(name string) {
fmt.Println(name, desc)
name, desc = "bb", "cc"
fmt.Println(name, desc)
}("aa")
fmt.Println(name, desc)
}
示例3 作用域 中声明
package main
import "fmt"
func main() {
name, desc := "xx", "i'm xx"
func(name string) {
fmt.Println(name, desc)
name, desc := "bb", "cc"
fmt.Println(name, desc)
}("aa")
fmt.Println(name, desc)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run block.go
aa i'm xx
bb cc
xx i'm xx
*/
高阶函数
函数作为返回值 - 闭包 close.go
示例1
package main
import "fmt"
func addBase(base int) func(int) int {
fmt.Println(base)
return func(n int) int {
return n
}
}
func main() {
addBase(1)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run close.go
1
*/
示例2
package main
import "fmt"
func addBase(base int) func(int) int {
fmt.Println(base)
return func(n int) int {
return n + base
}
}
func main() {
add1 := addBase(1)
fmt.Println(add1(5))
add10 := addBase(10)
fmt.Println(add10(3))
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run close.go
1
6
10
13
*/
匿名函数应用
sort.Slice
package main
import (
"fmt"
"sort"
)
func main() {
// char => counter
// A=>65
// B=>66
// C=>67
// D=>68
stats := [][]int{{'A', 3}, {'B', 2}, {'c', 1}, {'D', 2}}
//使用出现的次数进行排序
sort.Slice(stats, func(i, j int) bool {
return stats[i][1] > stats[j][1]
})
fmt.Println(stats)
}
sort.SliceStable
package main
import (
"fmt"
"sort"
)
func main() {
// char => counter
// A=>65
// B=>66
// C=>67
// D=>68
stats := [][]int{{'A', 3}, {'B', 2}, {'c', 1}, {'D', 2}}
//使用出现的次数进行排序
// {B,2},{D,2}=> 稳定的
// {D,2},{B,2}=> 不稳定的
sort.Slice(stats, func(i, j int) bool {
return stats[i][1] > stats[j][1]
})
// sort.SliceStable(stats, func(i, j int) bool {
// return stats[i][1] > stats[j][1]
// })
fmt.Println(stats)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run sort.go
[[65 3] [66 2] [68 2] [99 1]]
*/
sort.Search
package main
import (
"fmt"
"sort"
)
func main() {
// char => counter
// A=>65
// B=>66
// C=>67
// D=>68
stats := [][]int{{'A', 3}, {'B', 2}, {'c', 1}, {'D', 2}}
//使用出现的次数进行排序
sort.Slice(stats, func(i, j int) bool {
return stats[i][1] > stats[j][1]
})
// sort.SliceStable(stats, func(i, j int) bool {
// return stats[i][1] > stats[j][1]
// })
fmt.Println(stats)
//升序 <=
//降序 >=
// 对stats升序排序<=,查询stats[i][1]是1的元素的索引 是3
index := sort.Search(len(stats), func(i int) bool {
return stats[i][1] <= 1
})
fmt.Println(index)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run sort.go
[[65 3] [66 2] [68 2] [99 1]]
3
*/
练习 todolist
// 做一个命令行的任务管理
// 用户管理
// 1 函数,输入&输出,符合数据结构
// 2 了解流程(对数据的操作流程,增、删、改、查)
// 1 任务的输入(添加任务)
// 2 任务列表(任务查询)
// 3 任务修改
// 4 任务删除
// 5 详情
// 任务
// ID,任务名称,开始时间,结束时间,状态,负责人
// ID,name,start_time,end_time,status,user
// []map[string][string]
示例1-新增功能
1 创建todos map切片
2 添加常量(任务名 ...)
任务名 开始、结束时间 状态 用户名 等
3 添加newTask函数
4 通过scan获取,append加入切片
package main
import "fmt"
var todos = make([]map[string]string, 0)
const (
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func newTask() map[string]string {
task := make(map[string]string)
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
func main() {
var text string
task := newTask()
task[endTime] = ""
task[status] = "新创建"
fmt.Println("请输入任务信息:")
fmt.Print("任务名:")
fmt.Scan(&text)
task[name] = text
fmt.Print("开始时间:")
fmt.Scan(&text)
task[startTime] = text
fmt.Print("负责人:")
fmt.Scan(&text)
task[user] = text
todos = append(todos, task)
fmt.Println(todos)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306\todolist>go run add.go
请输入任务信息:
任务名:todo01
开始时间:19:00
负责人:tt
[map[end_time: name:todo01 start_time:19:00 status:新创建 user:tt]]
*/
示例1-新增扩展
1 添加数据到todos map切片
package main
import (
"fmt"
"strconv"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
2 添加常量(id 完成 ...)
完成、未完成、id等字段
package main
import (
"fmt"
"strconv"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
3 添加genId函数
字符串转换为int
todoId, _ := strconv.Atoi(todo["id"])
func genId() int {
var rt int
for _, todo := range todos {
todoId, _ := strconv.Atoi(todo["id"])
if rt < todoId {
rt = todoId
}
}
return rt + 1
}
4 函数newTask添加task[id]
func newTask() map[string]string {
//id生成(用todos中最大的ID+1)
task := make(map[string]string)
task[id] = strconv.Itoa(genId())
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
5 新增功能测试
package main
import (
"fmt"
"strconv"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func genId() int {
var rt int
for _, todo := range todos {
todoId, _ := strconv.Atoi(todo["id"])
if rt < todoId {
rt = todoId
}
}
return rt + 1
}
func newTask() map[string]string {
//id生成(用todos中最大的ID+1)
task := make(map[string]string)
task[id] = strconv.Itoa(genId())
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
func main() {
var text string
task := newTask()
task[endTime] = ""
task[status] = "新创建"
fmt.Println("请输入任务信息:")
fmt.Print("任务名:")
fmt.Scan(&text)
task[name] = text
fmt.Print("开始时间:")
fmt.Scan(&text)
task[startTime] = text
fmt.Print("负责人:")
fmt.Scan(&text)
task[user] = text
todos = append(todos, task)
fmt.Println(todos)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306\todolist>go run add.go
请输入任务信息:
任务名:做饭
开始时间:19:00
负责人:xx
[map[end_time: id:1 name:陪孩子散步 start_time:18:00 status:未完成 user:xx] map[end_time: id:2 name:备课 start_time:21:00 status:未完成 user:xx] map[end_time: id:4 name:复习 start_time:09:00 status:未完成 user:xx] map[end_time: id:5 name:做饭 start_time:19:00 status:新创建 user:xx]]
*/
示例2 查询功能 query.go
1 补充数据到todos map切片
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "5", "name": "准备上课", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "6", "name": "课堂笔记", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
2 添加打印函数(分割符strings.Repeat)
func printTask(task map[string]string) {
fmt.Println(strings.Repeat("-", 20))
fmt.Println("ID", task[id])
fmt.Println("任务名:", task[name])
fmt.Println("开始时间:", task[startTime])
fmt.Println("完成时间:", task[endTime])
}
3 查询todo[name]字段,包含某个字符串
func main() {
var text string
fmt.Print("请输入查询信息:")
fmt.Scan(&text)
for _, todo := range todos {
if strings.Contains(todo[name], text) {
printTask(todo)
}
}
}
4 查询功能测试
package main
import (
"fmt"
"strings"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "5", "name": "准备上课", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "6", "name": "课堂笔记", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func printTask(task map[string]string) {
fmt.Println(strings.Repeat("-", 20))
fmt.Println("ID", task[id])
fmt.Println("任务名:", task[name])
fmt.Println("开始时间:", task[startTime])
fmt.Println("完成时间:", task[endTime])
}
func main() {
var text string
fmt.Print("请输入查询信息:")
fmt.Scan(&text)
for _, todo := range todos {
if strings.Contains(todo[name], text) {
printTask(todo)
}
}
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306\todolist>go run query.go
请输入查询信息:课
--------------------
ID 2
任务名: 备课
开始时间: 21:00
完成时间:
--------------------
ID 5
任务名: 准备上课
开始时间: 09:00
完成时间:
--------------------
ID 6
任务名: 课堂笔记
开始时间: 09:00
完成时间:
*/
示例3 todolist.go
1 复制代码到todolist.go
共有部分:
复制todos变量,复制常量,
add.go部分:
复制genId函数,复制newTask函数
query.go部分:
复制printTask函数
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "5", "name": "准备上课", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "6", "name": "课堂笔记", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func genId() int {
var rt int
for _, todo := range todos {
todoId, _ := strconv.Atoi(todo["id"])
if rt < todoId {
rt = todoId
}
}
return rt + 1
}
func newTask() map[string]string {
//id生成(用todos中最大的ID+1)
task := make(map[string]string)
task[id] = strconv.Itoa(genId())
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
func printTask(task map[string]string) {
fmt.Println(strings.Repeat("-", 20))
fmt.Println("ID", task[id])
fmt.Println("任务名:", task[name])
fmt.Println("开始时间:", task[startTime])
fmt.Println("完成时间:", task[endTime])
}
2 新增for循环
选择功能 if else
func main() {
for {
fmt.Print("请输入操作(add/query/..../):")
var text string
fmt.Scan(&text)
if text == "add" {
} else if text == "query" {
} else if text == "modify" {
} else if text == "delete" {
} else {
fmt.Println("输入指令不正确")
}
}
}
改为switch case
func main() {
for {
fmt.Print("请输入操作(add/query/..../):")
var text string
fmt.Scan(&text)
// if text == "add" {
// } else if text == "query" {
// } else if text == "modify" {
// } else if text == "delete" {
// } else {
// fmt.Println("输入指令不正确")
// }
switch text {
case "add":
case "query":
case "modify":
case "delete":
default:
fmt.Println("输入指令错误")
}
}
}
3 完善for循环
添加任务代码
case "add":
var text string
task := newTask()
fmt.Println("请输入任务信息:")
fmt.Print("任务名:")
fmt.Scan(&text)
task[name] = text
fmt.Print("开始时间:")
fmt.Scan(&text)
task[startTime] = text
fmt.Print("负责人:")
fmt.Scan(&text)
task[user] = text
todos = append(todos, task)
fmt.Println("创建任务成功")
case "query":
查询任务代码
case "query":
var text string
fmt.Print("请输入查询信息:")
fmt.Scan(&text)
for _, todo := range todos {
if strings.Contains(todo[name], text) {
printTask(todo)
}
}
case "modify":
测试添加和查询
/*打印结果
D:\GoWork\src\go_course\day03-20230306\todolist>go run todolist.go
请输入操作(add/query/..../):add
请输入任务信息:
任务名:做饭
开始时间:15:00
负责人:xx
创建任务成功
请输入操作(add/query/..../):query
请输入查询信息:饭
--------------------
ID 7
任务名: 做饭
开始时间: 15:00
完成时间:
请输入操作(add/query/..../):
*/
添加退出功能
break跳出switch层,没有跳出for层,使用label退出。或者打印exit后return
func main() {
EXIT:
for {
fmt.Print("请输入操作(add/query/..../exit/):")
var text string
fmt.Scan(&text)
switch text {
case "add":
/*......*/
case "query":
/*......*/
case "modify":
case "delete":
case "exit":
fmt.Println("exit")
break EXIT
default:
fmt.Println("输入指令错误")
}
}
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306\todolist>go run todolist.go
请输入操作(add/query/..../):exit
exit
*/
第一阶段 完整代码
package main
import (
"fmt"
"strconv"
"strings"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "5", "name": "准备上课", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "6", "name": "课堂笔记", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func genId() int {
var rt int
for _, todo := range todos {
todoId, _ := strconv.Atoi(todo["id"])
if rt < todoId {
rt = todoId
}
}
return rt + 1
}
func newTask() map[string]string {
//id生成(用todos中最大的ID+1)
task := make(map[string]string)
task[id] = strconv.Itoa(genId())
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
func printTask(task map[string]string) {
fmt.Println(strings.Repeat("-", 20))
fmt.Println("ID", task[id])
fmt.Println("任务名:", task[name])
fmt.Println("开始时间:", task[startTime])
fmt.Println("完成时间:", task[endTime])
}
func main() {
for {
fmt.Print("请输入操作(add/query/..../exit/):")
var text string
fmt.Scan(&text)
// if text == "add" {
// } else if text == "query" {
// } else if text == "modify" {
// } else if text == "delete" {
// } else {
// fmt.Println("输入指令不正确")
// }
switch text {
case "add":
var text string
task := newTask()
fmt.Println("请输入任务信息:")
fmt.Print("任务名:")
fmt.Scan(&text)
task[name] = text
fmt.Print("开始时间:")
fmt.Scan(&text)
task[startTime] = text
fmt.Print("负责人:")
fmt.Scan(&text)
task[user] = text
todos = append(todos, task)
fmt.Println("创建任务成功")
case "query":
var text string
fmt.Print("请输入查询信息:")
fmt.Scan(&text)
for _, todo := range todos {
if strings.Contains(todo[name], text) {
printTask(todo)
}
}
case "modify":
case "delete":
case "exit":
fmt.Println("exit")
// break EXIT
return
default:
fmt.Println("输入指令错误")
}
}
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306\todolist>go run todolist.go
请输入操作(add/query/..../exit/):add
请输入任务信息:
任务名:上课
开始时间:09:00
负责人:xx
创建任务成功
请输入操作(add/query/..../exit/):query
请输入查询信息:课
--------------------
ID 2
任务名: 备课
开始时间: 21:00
完成时间:
--------------------
ID 5
任务名: 准备上课
开始时间: 09:00
完成时间:
--------------------
ID 6
任务名: 课堂笔记
开始时间: 09:00
完成时间:
--------------------
ID 7
任务名: 上课
开始时间: 09:00
完成时间:
请输入操作(add/query/..../exit/):exit
exit
*/
代码抽象为函数
func add() {
var text string
task := newTask()
fmt.Println("请输入任务信息:")
fmt.Print("任务名:")
fmt.Scan(&text)
task[name] = text
fmt.Print("开始时间:")
fmt.Scan(&text)
task[startTime] = text
fmt.Print("负责人:")
fmt.Scan(&text)
task[user] = text
todos = append(todos, task)
fmt.Println("创建任务成功")
}
func query() {
var text string
fmt.Print("请输入查询信息:")
fmt.Scan(&text)
for _, todo := range todos {
if strings.Contains(todo[name], text) {
printTask(todo)
}
}
}
//调用
...
switch text {
case "add":
add()
case "query":
query()
case "modify":
...
重复代码再提取input
重复部分:声明text 打印操作信息,scan接收变量指针,返回text内容赋值
func input(prompt string) string {
var text string
fmt.Print(prompt)
fmt.Scan(&text)
return strings.TrimSpace(text)
}
package main
import (
"fmt"
"strconv"
"strings"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "5", "name": "准备上课", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "6", "name": "课堂笔记", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func input(prompt string) string {
var text string
fmt.Print(prompt)
fmt.Scan(&text)
return strings.TrimSpace(text)
}
func genId() int {
var rt int
for _, todo := range todos {
todoId, _ := strconv.Atoi(todo["id"])
if rt < todoId {
rt = todoId
}
}
return rt + 1
}
func newTask() map[string]string {
//id生成(用todos中最大的ID+1)
task := make(map[string]string)
task[id] = strconv.Itoa(genId())
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
func printTask(task map[string]string) {
fmt.Println(strings.Repeat("-", 20))
fmt.Println("ID", task[id])
fmt.Println("任务名:", task[name])
fmt.Println("开始时间:", task[startTime])
fmt.Println("完成时间:", task[endTime])
}
func add() {
//var text string
task := newTask()
fmt.Println("请输入任务信息:")
// fmt.Print("任务名:")
// fmt.Scan(&text)
// task[name] = text
task[name] = input("任务名:")
// fmt.Print("开始时间:")
// fmt.Scan(&text)
// task[startTime] = text
task[startTime] = input("开始时间:")
// fmt.Print("负责人:")
// fmt.Scan(&text)
// task[user] = text
task[user] = input("负责人:")
todos = append(todos, task)
fmt.Println("创建任务成功")
}
func query() {
// var text string
// fmt.Print("请输入查询信息:")
// fmt.Scan(&text)
q := input("请输入查询信息:")
for _, todo := range todos {
// if strings.Contains(todo[name], text) {
if strings.Contains(todo[name], q) {
printTask(todo)
}
}
}
func main() {
for {
// fmt.Print("请输入操作(add/query/..../exit/):")
// var text string
// fmt.Scan(&text)
text := input("请输入操作(add/query/..../exit/):")
// if text == "add" {
// } else if text == "query" {
// } else if text == "modify" {
// } else if text == "delete" {
// } else {
// fmt.Println("输入指令不正确")
// }
switch text {
case "add":
add()
case "query":
query()
case "modify":
case "delete":
case "exit":
fmt.Println("exit")
// break EXIT
return
default:
fmt.Println("输入指令错误")
}
}
}
省略变量,再提取
package main
import (
"fmt"
"strconv"
"strings"
)
// var todos = make([]map[string]string, 0)
var todos = []map[string]string{
{"id": "1", "name": "陪孩子散步", "start_time": "18:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "2", "name": "备课", "start_time": "21:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "4", "name": "复习", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "5", "name": "准备上课", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
{"id": "6", "name": "课堂笔记", "start_time": "09:00", "end_time": "", "status": statusNew, "user": "xx"},
}
const (
statusNew = "未完成"
statusComplete = "完成"
)
const (
id = "id"
name = "name"
startTime = "start_time"
endTime = "end_time"
status = "status"
user = "user"
)
func input(prompt string) string {
var text string
fmt.Print(prompt)
fmt.Scan(&text)
return strings.TrimSpace(text)
}
func genId() int {
var rt int
for _, todo := range todos {
todoId, _ := strconv.Atoi(todo["id"])
if rt < todoId {
rt = todoId
}
}
return rt + 1
}
func newTask() map[string]string {
//id生成(用todos中最大的ID+1)
task := make(map[string]string)
task[id] = strconv.Itoa(genId())
task[name] = ""
task[startTime] = ""
task[endTime] = ""
task[status] = "新创建"
task[user] = ""
return task
}
func printTask(task map[string]string) {
fmt.Println(strings.Repeat("-", 20))
fmt.Println("ID", task[id])
fmt.Println("任务名:", task[name])
fmt.Println("开始时间:", task[startTime])
fmt.Println("完成时间:", task[endTime])
}
func add() {
task := newTask()
fmt.Println("请输入任务信息:")
task[name] = input("任务名:")
task[startTime] = input("开始时间:")
task[user] = input("负责人:")
todos = append(todos, task)
fmt.Println("创建任务成功")
}
func query() {
//q := input("请输入查询信息:")
for _, todo := range todos {
//if strings.Contains(todo[name], q) {
if strings.Contains(todo[name], input("请输入查询信息:")) {
printTask(todo)
}
}
}
func main() {
for {
//text := input("请输入操作(add/query/..../exit/):")
//switch text {
switch input("请输入操作(add/query/..../exit/):") {
case "add":
add()
case "query":
query()
case "modify":
case "delete":
case "exit":
fmt.Println("exit")
return
default:
fmt.Println("输入指令错误")
}
}
}
第二阶段 重构v2
func main() {
methods := map[string]func(){
"add": add,
"query": query,
}
for {
text := input("请输入操作(add/query/..../exit/):")
// switch text {
// case "add":
// add()
// case "query":
// query()
// case "modify":
// case "delete":
// case "exit":
// fmt.Println("exit")
// return
// default:
// fmt.Println("输入指令错误")
// }
if text == "exit" {
break
}
method, ok := methods[text]
if ok {
method()
} else {
fmt.Println("输入指令不正确")
}
}
}
改写为1行
func main() {
methods := map[string]func(){
"add": add,
"query": query,
}
for {
text := input("请输入操作(add/query/..../exit/):")
if text == "exit" {
break
}
if method, ok := methods[text]; ok {
method()
} else {
fmt.Println("输入指令不正确")
}
}
}
作业
1 知识整理
2 我有一个梦想 中出现次数最多的top 10 字符集出现次数
3 统计
a 每个IP出现次数
b 每个状态码出现次数
c 每个IP在每个URL上产生的流量
int[][4]string{
// ip url 状态码 字节大小
{"1.1.1.1","/index.html","200","1000"},
{"1.1.1.2","/index.html","200","10000"},
{"1.1.1.1","/index.html","200","10000"}
}
key:map 必须是可以使用==进行比较的数据类型
key 数据类型,ip+url =>string key
[]string{ip,url}
[2]string{ip,url}
4 todo管理
a 编辑
请输入编辑的ID
通过ID查找=>Task =>显示
用户确认是否进行编辑(y/yes):编辑
用户输入:任务名称,开始时间,状态
//状态如果是已完成,初始化完成时间
//time.Now().Format("2006-01-02 15:04:05")
b删除
请输入编辑的ID
通过ID查找 =>Task =>显示
用户确认是否进行删除(y/yes):删除
c数据验证(用户输入数据检查)
任务名称:不能重复(新增,编辑)
编辑:
a,任务名称不变
b. 任务名称改成其他已存在的
任务状态:
新创建,开始执行,已完成,暂停
错误处理
package main
import (
"errors"
"fmt"
"strconv"
)
func div(n1, n2 int) (int, error) {
if n2 == 0 {
return -1, errors.New("除数为0")
}
return n1 / n2, nil
}
func main() {
value, err := strconv.Atoi("xxx")
fmt.Printf("%T\n", err)
fmt.Println(err)
fmt.Println(value)
e := fmt.Errorf("自定义错误")
fmt.Printf("%T %#v\n", e, e)
e2 := errors.New("自定义错误2")
fmt.Printf("%T %#v\n", e2, e2)
//go语言
//希望程序内部如果有错误
//通过最后一个返回值显示返回给调用者
//由调用者决定如何处理
if rt, err := div(1, 0); err == nil {
fmt.Println(rt)
} else {
fmt.Println(err)
}
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run error.go
*strconv.NumError
strconv.Atoi: parsing "xxx": invalid syntax
0
*errors.errorString &errors.errorString{s:"自定义错误"}
*errors.errorString &errors.errorString{s:"自定义错误2"}
除数为0
*/
延迟声明main()函数中 defer
package main
import "fmt"
func main() {
//defer 函数调用
// 延迟执行,在函数退出之前
defer func() {
fmt.Println("defer")
}()
defer func() {
fmt.Println("defer A")
}()
defer func() {
fmt.Println("defer B")
}()
fmt.Println("main")
}
延迟声明test()函数中 defer
package main
import "fmt"
func test() string {
//defer 函数调用
// 延迟执行,在函数退出之前
defer func() {
fmt.Println("defer")
}()
defer func() {
fmt.Println("defer A")
}()
defer func() {
fmt.Println("defer B")
}()
fmt.Println("test")
return "test--"
}
func main() {
fmt.Println(test())
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run defer.go
test
defer B
defer A
defer
test--
*/
延迟声明defer中不要修改返回值
package main
import "fmt"
func test() (rt string) {
//defer 函数调用
// 延迟执行,在函数退出之前
defer func() {
fmt.Println("defer")
rt = "defer"
}()
defer func() {
fmt.Println("defer A")
}()
defer func() {
fmt.Println("defer B")
}()
fmt.Println("test")
rt = "test--"
return
}
func main() {
fmt.Println(test())
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run defer.go
test
defer B
defer A
defer
defer
*/
defer使用
package main
import "fmt"
func test() (rt string) {
//defer 函数调用
// 延迟执行,在函数退出之前
defer func() {
fmt.Println("defer")
rt = "defer"
}()
defer func() {
fmt.Println("defer A")
}()
defer func() {
fmt.Println("defer B")
}()
fmt.Println("test")
rt = "test--"
return
}
func test2(n1, n2 int) {
defer func() {
//函数体内不管是否发生错误,都会执行
fmt.Println("test2 defer")
}()
fmt.Println("before")
fmt.Println(n1 / n2)
fmt.Println("after")
}
func main() {
fmt.Println(test())
test2(1, 0)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run defer.go
test
defer B
defer A
defer
defer
before
test2 defer
panic: runtime error: integer divide by zero
goroutine 1 [running]:
main.test2(0x1, 0x0)
D:/GoWork/src/go_course/day03-20230306/defer.go:29 +0x146
main.main()
D:/GoWork/src/go_course/day03-20230306/defer.go:35 +0x65
exit status 2
*/
defer在for循环中使用 forerror.go
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
fmt.Println("for before", i)
//打开文件
//延迟关闭
//处理(处理出现错误)
defer func() {
fmt.Println("defer", i)
}()
fmt.Println("for after", i)
}
fmt.Println("main")
}
D:\GoWork\src\go_course\day03-20230306>go run forerror.go
for before 0
for after 0
for before 1
for after 1
for before 2
for after 2
main
defer 3
defer 3
defer 3
处理
在for循环中defer ,导致for循环一直使用defer 函数没有退出,一直没有释放defer
处理:单独添加一个func函数,在函数中defer
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
func (){
//打开文件
//延迟关闭
// defer
//处理
}()
fmt.Println("for before", i)
defer func() {
fmt.Println("defer", i)
}()
fmt.Println("for after", i)
}
fmt.Println("main")
}
使用赋值1
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
a := i
fmt.Println("for before", i)
defer func() {
fmt.Println("defer", a)
}()
fmt.Println("for after", i)
}
fmt.Println("main")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run forerror.go
for before 0
for after 0
for before 1
for after 1
for before 2
for after 2
main
defer 2
defer 1
defer 0
*/
使用局部定义的i
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
fmt.Println("for before", i)
defer func(i int) {
fmt.Println("defer", i)
}(i)
fmt.Println("for after", i)
}
fmt.Println("main")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run forerror.go
for before 0
for after 0
for before 1
for after 1
for before 2
for after 2
main
defer 2
defer 1
defer 0
*/
panic
package main
import "fmt"
func test() {
fmt.Println("before")
panic("自定义panic")
fmt.Println("after")
}
func main() {
test()
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before
panic: 自定义panic
goroutine 1 [running]:
main.test()
D:/GoWork/src/go_course/day03-20230306/panic.go:7 +0x65
main.main()
D:/GoWork/src/go_course/day03-20230306/panic.go:12 +0x17
exit status 2
*/
defer在panic前
package main
import "fmt"
func test() {
defer func() {
fmt.Println("defer")
}()
fmt.Println("before")
panic("自定义panic")
fmt.Println("after")
}
func main() {
test()
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before
defer
panic: 自定义panic
goroutine 1 [running]:
main.test()
D:/GoWork/src/go_course/day03-20230306/panic.go:10 +0x8b
main.main()
D:/GoWork/src/go_course/day03-20230306/panic.go:15 +0x17
exit status 2
*/
使用recover并打印类型
package main
import "fmt"
func test() {
// recover 必须在延迟执行函数内
defer func() {
fmt.Println("defer")
err := recover()
//打印类型
fmt.Printf("%T,%#v\n", err, err)
}()
fmt.Println("before")
panic("自定义panic")
fmt.Println("after")
}
func main() {
fmt.Println("before main")
test()
fmt.Println("after main")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before main
before
defer
string,"自定义panic"
after main
*/
没有发生panic,仍然执行recover
package main
import "fmt"
func test() {
// recover 必须在延迟执行函数内
defer func() {
fmt.Println("defer")
err := recover()
//打印类型
fmt.Printf("%T,%#v\n", err, err)
}()
fmt.Println("before")
// panic("自定义panic")
fmt.Println("after")
}
func main() {
fmt.Println("before main")
test()
fmt.Println("after main")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before main
before
after
defer
<nil>,<nil>
after main
*/
修改增加判断
package main
import "fmt"
func test() {
// recover 必须在延迟执行函数内
defer func() {
fmt.Println("defer")
//打印类型
if err := recover(); err != nil {
fmt.Printf("%T,%#v\n", err, err)
}
}()
fmt.Println("before")
// panic("自定义panic")
fmt.Println("after")
}
func main() {
fmt.Println("before main")
test()
fmt.Println("after main")
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before main
before
after
defer
after main
*/
返回值,接收err返回
package main
import "fmt"
func test() (err error) {
// recover 必须在延迟执行函数内
defer func() {
fmt.Println("defer")
//打印类型
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s", panicErr)
}
}()
fmt.Println("before")
panic("自定义panic")
fmt.Println("after")
return err
}
func main() {
fmt.Println("before main")
err := test()
fmt.Println("after main", err)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before main
before
defer
after main 自定义panic
*/
errors.New()
package main
import (
"errors"
"fmt"
)
func test() (err error) {
// recover 必须在延迟执行函数内
defer func() {
fmt.Println("defer")
//打印类型
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s", panicErr)
}
}()
fmt.Println("before")
// panic("自定义panic")
err = errors.New("xxx")
//检查所有的数据,连接,资源。。。
//用别人的库的时候,panic
fmt.Println("after")
return err
}
func main() {
fmt.Println("before main")
err := test()
fmt.Println("after main", err)
}
/*打印结果
D:\GoWork\src\go_course\day03-20230306>go run panic.go
before main
before
after
defer
after main xxx
*/
包
了解gopath
//D:\GoWork\src\go_course\day03-20230306\main\main.go
package main
import "fmt"
var mainVar = "man Var"
func mainFunc() {
fmt.Println("main func")
}
func main() {
mainFunc()
utilsFunc()
fmt.Println(mainVar)
fmt.Println(utilsVar)
}
//D:\GoWork\src\go_course\day03-20230306\main\utils.go
package main
import "fmt"
var utilsVar = "utils Var"
func utilsFunc() {
fmt.Println("utils Func")
}
/*打印结果
1 关闭set GO111MODULE=off
2 D:\GoWork\src\go_course\day03-20230306\main>go build
3 D:\GoWork\src\go_course\day03-20230306\main>main.exe
main func
utils Func
man Var
utils Var
*/
// GO PATH项目
// GOPATH GOMODULE
// GO包
// 1.同一个文件夹下所有go文件的包名,必须一致
// 2. 关闭了 GOMODULE
// GOPATH在项目目录直接运行go build无文件名
// 将当前文件夹下的所有go文件进行编译
// 3. main包编译为可执行程序
// 4. main包中只能有一个main函数
// GOPATH 环境变量信息,定义多个目录
// src ==> 源文件
// pkg ==> 程序编译的包文件
// bin ==> 程序编译的可执行文件
测试使用
go build test
go install test
/*路径结构
D:\GoWork\src\go_course\day03-20230306\main\bin\
D:\GoWork\src\go_course\day03-20230306\main\pkg\
D:\GoWork\src\go_course\day03-20230306\main\src\test\main.go
D:\GoWork\src\go_course\day03-20230306\main\src\test\test.go
*/
/*执行结果
D:\GoWork\src\go_course\day03-20230306\main>set GOPATH=D:\GoWork\src\go_course\day03-20230306\main;%GOPATH%
D:\GoWork\src\go_course\day03-20230306\main>echo %GOPATH%
D:\GoWork\src\go_course\day03-20230306\main;D:\GoWork
D:\GoWork\src\go_course\day03-20230306\main>cd src
D:\GoWork\src\go_course\day03-20230306\main\src>ls -la
total 0
drwxr-xr-x 1 zhu 197121 0 3月 12 16:25 .
drwxr-xr-x 1 zhu 197121 0 3月 12 16:25 ..
drwxr-xr-x 1 zhu 197121 0 3月 12 16:25 test
D:\GoWork\src\go_course\day03-20230306\main\src>go build test
D:\GoWork\src\go_course\day03-20230306\main\src>test.exe
main func
utils Func
man Var
utils Var
*/
/*执行 go install test 相当于生成test.go 后拷贝到bin目录下
D:\GoWork\src\go_course\day03-20230306\main\src>go install test
*/
go install pkg
package pkg
var utilsVar = "utils Var"
/*打印结果
文件及目录:
D:\GoWork\src\go_course\day03-20230306\main\src\pkg\utils.go
执行:
D:\GoWork\src\go_course\day03-20230306\main\src>go install pkg
D:\GoWork\src\go_course\day03-20230306\main\src>
使用 go install pkg 会在pkg下生成pkg.a文件
D:\GoWork\src\go_course\day03-20230306\main\pkg\windows_amd64\pkg.a
*/
注意 包内和包外 函数名大小写问题