这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记,非常感谢字节跳动无偿地分享技术知识并细致地讲解指导。本篇笔记主要介绍go语言的基础语法知识。
一、输入输出
1) 打印输出
类似于Python,比较简单。
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world") //末尾补回车; fmt包的函数
print("hello world") //直接打印,不补回车; 新版本go语言内置函数
println("hello world") //末尾补回车; 新版本go语言内置函数
}
2) 标准输入
类似于C语言,参数、用法都差不多。
package main
import (
"fmt"
)
func main() {
var a int
fmt.Scanf("%d\n", &a) // 基本就是c语言的scanf
println("a = ", a)
fmt.Scanln(&a) // 扫描一行,遇到换行符或EOF就停止
println("a = ", a)
}
二、变量常量
var表示变量,const表示常量,类型在变量名后面,支持类型推导,还支持简单变量申明。
注意:go语言支持指针,用法与c语言基本一致,“ * ”是指针,“ & ”是取地址。
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 + "foo"
fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
fmt.Println(g) // initialfoo
const s string = "constant"
const h = 500000000
const i = 3e20 / h
fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}
三、条件语句
格式限制严格,“ if 表达式 { ” 必须在同一行,“ } else { ” 必须在同一行。
package main
import "fmt"
func main() {
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
if 8%4 == 0 {
fmt.Println("8 is divisible by 4")
}
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
}
四、循环语句
只有一个for关键字,承担while和for的功能。
package main
import "fmt"
func main() {
i := 1
for {
fmt.Println("loop")
break
}
for j := 7; j < 9; j++ {
fmt.Println(j)
}
for n := 0; n < 5; n++ {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
}
五、分支语句
switch功能与c语言中的switch类似,只是不需要加break就有c语言中加了break的含义。
package main
import (
"fmt"
"time"
)
func main() {
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")
}
}
六、数组与切片
数组,直接在类型前面加上[len]即可,多个[]就是多维数组;[]中没有具体数值时就是一个切片。
切片,类似于python的列表[],就是长度可变的数组。“ var a []int ” 创建长度为0的切片,“ a := make([]int, 3) ” 创建长度为3的切片。
package main
import "fmt"
func main() {
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]
}
七、映射map
类型关键字为“ map[key_type]value_type ”,创建方式类似于切片,可以用var关键字创建,也可用make创建。用法类似于c++的map和python的字典。
package main
import "fmt"
func main() {
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(len(m)) // 2
fmt.Println(m["one"]) // 1
fmt.Println(m["unknow"]) // 0
r, ok := m["unknow"]
fmt.Println(r, ok) // 0 false
delete(m, "one") // 删除one索引和对应的值
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)
}
八、函数
函数定义格式为:“ func 函数名(参数列表) 返回值类型 { ”,前面的main函数就是标准的无返回值函数。此外,函数参数列表可以简写为如下形式:
func add2(a, b int) int {
return a + b
}
九、结构体(类)
只有一个struct关键字,没有class关键字;struct中只能定义数据成员,不能定义函数成员。
所有的类成员函数需要定义为如下形式,才能通过 . 操作访问:
type user struct {
name string
password string
}
func (u user) checkPassword(password string) bool {
return u.password == password
}
十、错误处理
errors包提供错误处理,error是接口类型,是一种只含有未实现的方法的类。可以使用errors.New("not found")来创建一个错误。
PS: go语言有interface关键字,具体用法参见go语言中的interface使用实例_Golang_脚本之家 (jb51.net)
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
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
}
fmt.Println(u.name) // wang
if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err) // not found
return
} else {
fmt.Println(u.name)
}
}