这是我参与[第三届青训营-后端场]笔记创作活动的第一次笔记~
GO语法与C++或其他语言对比
- 1 go中同样有main函数,不过go的main函数必须在开始处使用package main来定义
-
2 go 中可以导入包,类比C++中的#include ,go中包的导入类似于python的包的导入:
-
例如(go的包的导入):import ( "fmt" )
-
-
3 go 中的变量定义
-
使用var定义变量
-
例如: var a = "initial" 定义了一个字符串类型的a变量 var b, c int = 1, 2 定义了两个整形的变量b, c(注:与C++相比,相当于把变量的类型放到了后面,然后赋值按顺序进行赋值)
-
-
使用
:=定义变量-
例如: var e float64 f := float32(e):定义变量f 注::= 定义变量时只能在函数内部,包括方法内
-
-
常量定义
-
go的常量定义类似于C++,使用const 例如: const s string = "constant"
-
-
-
go中的输出函数
-
go的输出函数有fmt.Println()[注:需要先导入fmt包],该函数类似于C的printf函数,只是该函数自动输出换行,C需要输入"\n"才能换行
-
-
go的除法
-
go的除法运算和C++类似,即8/5表示取得整数部分1
-
-
go的循环
-
go中没有while循环,go只有for循环,不过go的for循环有多种使用方法,可以达到类似while的使用 例如: 例一: for { //注:此种for循环就类似于C++的while(1) fmt.Println("loop") break } 例二: for j := 7; j < 9; j++ {//此种for循环就和正常的C++ for循环差不多,只是for循环不带括号 fmt.Println(j) } 例三: for i <= 3 {//此种for循环就和C++的while(i <= 3)代表同样的含义 fmt.Println(i) i = i + 1 } 总结:go的for循环非常灵活,即go中的for循环可以达到C++中的for循环和while的两种效果
-
-
go的条件语句
-
go的条件语句同样比较灵活,有以下几种用法 例一: if 7%2 == 0 {//该语句和C++的if,else语句类似,区别在于go中if的条件不用括号 fmt.Println("7 is even") } else { fmt.Println("7 is odd") } 例二: if num := 9; num < 0 {//此种方式是go独有的,即可以在if后面进行临时变量的简单定义 fmt.Println(num, "is negative") } else if num < 10 { fmt.Println(num, "has 1 digit") } else { fmt.Println(num, "has multiple digits") }
-
-
go中switch语句
-
1 go中的switch语句与C++的switch语句的区别在于,go中的switch语句不需要再每个条件下加break,不加时执行完该条件同样会跳出。 2 go中同样有default 3 go中的switch的case部分可以是表达式 例一: a := 2 switch a { case 1: fmt.Println("one") case 2: fmt.Println("two") case 3: fmt.Println("three") case 4, 5: fmt.Println("four or five") default: fmt.Println("other") } 例二: t := time.Now() switch { case t.Hour() < 12: fmt.Println("It's before noon") default: fmt.Println("It's after noon") }
-
-
go的数组定义
-
1 go的数组定义与C++类似,只是go的数组的定义遵循go的变量定义的规则 例一: var a [5]int //一位数组定义 var twoD [2][3]int //二维数组定义 2 go的数组元素的访问和C++相同 注:go的fmt.Println可以直接打印数组
-
-
go切片(slice)
-
由内置函数make创建切片
-
注:有make创建的切片各元素被默认初始化为切片元素类型的零值。 例一: s := make([]string, 3)//创建字符串切片,相当于C++的string s[3],即三个string类型的数组 例二: c := make([]string, len(s)) copy(c, s)//即可以利用copy函数将s的元素拷贝到c中 例三: go的切片和python类似,支持以下方式 假设s = [a b c d e f] 则s[2:5] 为 [c d e f] s[:]和s一样 s[:2]为 [a b] s[2:]和s[2:5]相同 例四: good := []string{"g", "o", "o", "d"}//创建时初始化 注:可以使用内置函数 append,copy 例: s = append(s, "d") s = append(s, "e", "f")
-
-
-
go的map
-
定义及访问如下,和C++类似 例一: m := make(map[string]int) m["one"] = 1 m["two"] = 2 例二: r, ok := m["unknow"]//go中独有的方式 其中m没有健"unknow",因此默认返回0 和 false fmt.Println(r, ok) // 0 false 例三: m2 := map[string]int{"one": 1, "two": 2} var m3 = map[string]int{"one": 1, "two": 2}
-
-
go的range函数
-
例一: nums := []int{2, 3, 4} sum := 0 for i, num := range nums { sum += num if num == 2 { fmt.Println("index:", i, "num:", num) // index: 0 num: 2 } } 其中,第一个i表示数组nums的索引,第二个表示nums[i]的值 例二: m := map[string]string{"a": "A", "b": "B"} for k, v := range m { fmt.Println(k, v) // b 8; a A } 其中,第一个k表示键,第二个v表示值 例三: for k := range m { fmt.Println("key", k) // key a; key b } 其中,如果m是个字典,则k表示键,m是个数组,则k表示索引
-
-
go的函数定义
-
go的函数定义和C++类似,不过有以下几点区别 1 定义函数时在开头使用func 关键字 2 定义函数时,函数的返回类型在形参的括号后指出 3 定义函数时,如果函数的形参列表类型相同,则可以省略前面的变量类型 例如: func add2(a, b int) int { return a + b } 4 定义函数时,可以自定义返回的格式 例如: func exists(m map[string]string, k string) (v string, ok bool) { v, ok = m[k] return v, ok }
-
-
go同样有指针,go的指针大致与C++相同
-
go中的结构体
-
结构体的定义
-
go中的结构体使用type关键字进行定义,例如: type user struct { name string password string } 1 使用结构体定义并初始化变量的几种方法: 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"
-
-
为自定义的结构体定义方法
-
注:该功能是go独有的,拿此例来说,为user这个自定义结构体定义一个方法,则使用该结构体定义的变量都可以访问该方法。 例一: func (u user) checkPassword(password string) bool { return u.password == password } func (u *user) resetPassword(password string) { u.password = password } //主函数 func main() { a := user{name: "wang", password: "1024"} a.resetPassword("2048") fmt.Println(a.checkPassword("2048")) // true }
-
-
-
go 的错误处理
-
//go的错误处理格式 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 } ... }
-
GO函数
string
strings.Contains,strings.Count,strings.HasPrefix,strings.HasSuffix,strings.Index,strings.Join,strings.Repeat,strings.Replace,strings.Split,strings.ToLower,strings.ToUpper
fmt
fmt.Println,fmt.Printf
注:Println不带格式化操作,Printf可以进行格式化输出(可以把该函数当做C语言的printf,只是把格式化输出符改变一下),格式化符如下:
%v:格局类型格式显示数据 如 s = "hello",则输出hello s = 123,则输出123
%+v:先输出字段类型,再输出该字段的值
%#v:先输出结构体名字值,再输出结构体(字段类型+字段的值)
%.2f 同C++
json
显示为json格式
API:json.Marshal,json.MarshalIndent,json.Unmarshal
例:
假设有结构体:
type userInfo struct {
Name string
Age int `json:"age"`
Hobby []string
}
有变量:a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
经过函数json.Marshal处理a后,处理的返回值为下图1
buf, err := json.Marshal(a)
经过函数json.MarshalIndent处理a后,如下图2
buf, err = json.MarshalIndent(a, "", "\t")
经过函数json.Unmarshal处理a后,如下图3
err = json.Unmarshal(buf, &b)
图1(buf)
图1(string(buf))
图2(string(buf))
图3(b)
time
time.Now,time.Date
例:
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t.Year,t.Month,t.Day,t.Hour,t.Minute,t.Sub
strconv
strconv.ParseFloat,strconv.ParseInt,strconv.ParseInt,strconv.Atoi,strconv.Atoi