省流不看版: 基础语法课程的笔记,可以说是毫无水平的教程照抄。
大部分操作都自己运行过,改了改参数什么的,Golang语法虽然有GPT老师,但自己写写还是最有用的学习方式,回想起了学期初一个月速成js+react去做项目网站的日子.......权当一个以后三天打鱼两天晒网查漏补缺巩固基础的笔记了。
变量类型
- 字符串是内置类型,可直接通过“+”拼接
- 变量声明
var a,b int = 1, 2
a,b := 1,2 // := 声明更简洁,可读性强
f :=float32(e)
const s string = "constant" //常量无确定类型,可根据使用上下文自己确定
if else
if 7%2 == 0 {
fmt.Println("7 is even") //条件没有括号,且必须跟大括号
}
唯一一种循环
for{
fmt.Println("死循环")
break
}
for j := 7; j < 9; j++ { //任何一段都可以省略
fmt.Println(j)
}
分支结构
switch a { //不需要加break
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3, 4:
fmt.Println("three or four")
default:
fmt.Println("other")
}
t := time.Now() // case可以使用任意变量类型,包括字符串和结构体
switch { //可以取代部分if else功能
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's afternoon")
}
数组
var a [5]int //存放5个int的数组
a[4] = 100
fmt.Println(a[4], len(a))
由于长度固定,业务中多用“切片”
切片
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
fmt.Println(s[1]) // b
s= append(s, "c", "d")
fmt.Println(s) // [a b c d] //由于切片长度为3但只赋2个值,故空出一位
s[2] = "c"
c := make([]string, len(s))
copy(c, s)
fmt.Println(c) // [a b c d]
fmt.Println(s[1:3]) // [b c]
map
//map
m := make(map[string]int) //string:key类型 value类型:int
m["one"] = 1
m["two"] = 2
fmt.Println(m, len(m), m["two"], m["three"]) //map[one:1 two:2] 2 2 0
//删除map的k-v对
delete(m, "one")
fmt.Println(m, len(m), m["two"], m["three"]) //map[two:2] 1 2 0
range
//range 数组
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
fmt.Println("index:", i, "num:", num) //index: 0 num: 2 index: 1 num: 3 index: 2 num: 4
}
fmt.Println(sum) // 9
//range map
maps := map[string]string{"a": "A", "b": "B"}
for k, v := range maps {
fmt.Println(k, v)
}
for k := range maps {
fmt.Println("key", k)
}
函数
// 函数:要写在func main()外部
func add(a int, b int) string {
sum := a + b
result := fmt.Sprintf("a+b的值是%d", sum)
return result
}
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
// `ok` 是一个布尔型的返回值,一般用于判断某个操作是否成功完成,这里是检查value是否存在
}
func main(){
aa, bb := 1, 2
fmt.Println(add(1, 2)) // a+b的值是3
testMap := map[string]string{"hello": "Hello", "world": "World"}
fmt.Println(exists(testMap, "hello")) // Hello true
fmt.Println(exists(testMap, "hi")) // false
fmt.Println(exists(testMap, "world")) // World true
}
指针
func add2(n int) {
n += 2 //这里操作的其实是n的副本,不会对原变量进行修改
}
func add2ptr(n *int) {
*n += 2 //指针就可以对原变量进行修改
}
func main() {
ptr := 5
add2(ptr)
fmt.Println(ptr) // 5
add2ptr(&ptr) //注意要加&取地址符,获取一个变量的指针
fmt.Println(ptr) // 7
结构体 大类型字段的集合
type user struct {
name string
password string
}
user_a := user{name: "wang", password: "1024"}
user_b := user{"wang", "1024"}
user_c := user{name: "wang"}
fmt.Println(user_a, user_b, user_c) // {wang 1024} {wang 1024} {wang }
user_c.password = "1024"
d := user{} // var d user
d.name = "wang"
d.password = "1024"
fmt.Println(d) //{wang 1024}
fmt.Println(&user_a) //&{wang 1024}
struct_ptr_A := &user_a
fmt.Println("name:", struct_ptr_A.name) // name: wang
fmt.Println("name:", user_b.name) // name: wang1
struct_ptr_A.password = "1234"
fmt.Println("修改后的A用户信息:", user_a) // 修改后的A用户信息: {wang 1234}
结构体方法
func (u user) checkPassword(password string) bool {
return u.password == password
}
func (u *user) resetPassword(password string) { //带指针可对结构体进行修改
u.password = password
}
//结构体方法
user_test := user{name: "zhang", password: "4321"}
fmt.Println("original password:", user_test.password) // original password: 4321
user_test.resetPassword("1234")
fmt.Println("new password:", user_test.password) // new password: 1234
fmt.Println(user_test.checkPassword("1234")) // true
错误处理
func findUsers(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")
}
//错误处理
u, err := findUsers([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name)
if u, err := findUsers([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err) // wang
return
} else {
fmt.Println(u.name) // not found
}
字符串操作
str_a := "hellolL"
fmt.Println(strings.Contains(str_a, "ll")) // true
fmt.Println(strings.Count(str_a, "l")) // 4
fmt.Println(strings.HasPrefix(str_a, "he")) // 判断字符串 str_a 是否以 he 开头
fmt.Println(strings.HasSuffix(str_a, "llo")) // 判断字符串 str_a 是否以 llo 结尾
fmt.Println(strings.Index(str_a, "ll")) // 2
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
fmt.Println(strings.Repeat(str_a, 2)) // hellollhelloll
fmt.Println(strings.Replace(str_a, "l", "L", -1)) // heLLoLL "-1"表示替换旧字符串次数,这里是替换所有
fmt.Println(strings.Split("a-b--c", "-")) // [a b c]
fmt.Println(strings.ToLower(str_a)) // helloll
fmt.Println(strings.ToTitle(str_a)) // HELLOLL
fmt.Println(len(str_a)) // 7
字符串格式化
%d用于输出十进制整数的值,例如fmt.Printf("%d", 42)将输出42。%v用于输出值的默认格式,例如fmt.Printf("%v", "hello")将输出"hello",而fmt.Printf("%v", 42)将输出42。%s用于输出字符串的值,例如fmt.Printf("%s", "hello")将输出"hello"。 除了这些常用的占位符之外,Go 语言还提供很多其他类型的占位符,如%f用于输出浮点数,%p用于输出指针地址等。
JSON处理
encoding/json包可以实现 JSON 编码和解码- 使用
json.Marshal()函数将 Go 中的数据类型编码为 JSON 字节数组 - 使用
json.MarshalIndent()函数将 Go 中的数据类型编码为缩进格式的 JSON 字节数组 - 使用
json.Unmarshal()函数将 JSON 字节数组解码为 Go 数据类型 - 在 JSON 编码和解码过程中,需要使用字节数组或字符串储存 JSON 数据
时间处理
// 创建时间对象并输出
now := time.Now()
fmt.Println("当前时间:", now)
// 使用时间常量并输出
delay := 3 * time.Second
fmt.Printf("延迟 %s 后执行任务...\n", delay)
// 时间延迟
time.Sleep(delay)
fmt.Println("任务执行中...")
// 时间格式化
t1 := time.Date(2022, time.May, 3, 10, 34, 0, 0, time.Local)
fmt.Println("时间格式化:", t1.Format("2006-01-02 15:04:05"))
// 时间定时器
fmt.Println("启动定时器...")
timer := time.NewTimer(5 * time.Second)
<-timer.C
fmt.Println("定时器时间到...")
timer.C 是一个类型为 <-chan time.Time(只能从通道中读取)的通道,表示定时器到期的时间。在定时器到期前,该通道会一直阻塞等待,直到定时器到期,通道中会发送一个时间事件给它的接收者。
Parse 函数适用于将时间字符串转换为 time.Time 类型,常用于从输入中解析年月日等日期信息。例如:
dateString := "2022-07-28"
fmt.Println(time.Parse("2006-01-02", dateString)) //2022-07-28 00:00:00 +0000 UTC <nil>
Unix 函数适用于将 Unix 时间戳(自 1970 年 1 月 1 日 00:00:00 UTC 起的秒数)转换为时间对象,或将时间对象转换为 Unix 时间戳。例如:
timestamp := int64(1659729852)
fmt.Println(time.Unix(timestamp, 0)) // 2022-08-06 04:04:12 +0800 CST
now := time.Now()
fmt.Println(now.Unix()) // 1683998108
Format 函数适用于将时间对象格式化为字符串,常用于将时间对象转换为易于读取的字符串。例如:
t2 := time.Date(2022, time.August, 1, 12, 0, 0, 0, time.UTC)
fmt.Println(t2.Format("2006-01-02 15:04:05")) // 2022-08-01 12:00:00
数字解析
strconv.ParseFloat 方法用于将字符串转换为 float64 类型的数值
strconv.ParseInt方法用于将字符串转换为指定进制下的 int64 类型的数值
strconv.Atoi方法用于将字符串转换为十进制下的 int 类型的数值
n1, err := strconv.Atoi(("AAA"))
fmt.Println(n1, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
n2, err := strconv.Atoi("123")
fmt.Println(n2, err) // 123 <nil>
进程信息
fmt.Println(os.Args)
fmt.Println(os.Getenv("PATH")) // 获取环境变量
fmt.Println(os.Setenv("AA", "BB")) // 设置环境变量
os.Command用于执行一个指定的命令。该函数会返回一个 *exec.Cmd 类型的指针,该指针包含了与执行命令相关的属性和方法,例如命令行参数、标准输入、标准输出、执行状态等。