这是我参与「第三届青训营 -后端场」笔记创作活动的的第一篇笔记
1.golang内置变量类型
- bool, string;
- (u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr;
- byte, rune
- float32, float64, complex64, complex128.
其中(u)int的位数由操作系统决定;
uintptr是指针;
byte和rune是int的别名,byte是8位rune是32位;
complex64的实部和虚部都是float32,complex128的实部和虚部都是float64。
go没有隐式类型转换,都要做显示的强制转换。
2.变量定义方式
方式一:使用var定义
var a = "initial"
var b, c int = 1, 2
var d = true
var e float64
方式二:使用:=定义
f := float32(e)
g := a + "foo"
常量定义
const s string = "constant"
const h = 500000000
const i = 3e20 / h
输出
fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
fmt.Println(g) // initialapple
fmt.Println(s, h, i) //constant 500000000 6e+11
3.条件语句
- if 后的条件判断不需要加括号
- if 后的大括号不能省略(即使只有一条执行语句)
- if 后面可以定义变量
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
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")
}
- switch 后的变量名不需要括号
- switch 中不用写break
- switch 后可以不加任何变量,直接在每个 case 处加判断语句
a := 2
switch a {
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()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
4.循环语句
golang里没有while,do while循环,只有一种for循环
i := 1
for { // 不写条件就是死循环
fmt.Println("loop")
break
}
for n := 0; n < 5; n++ {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
5.数组
定义方式:
var a [5]int
a[4] = 100
fmt.Println("get:", a[2])
fmt.Println("len:", 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++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
数组的长度是固定的,实际开发很少用,一般用切片slice
6.slice 切片(可变长度数组)
用 make 创建切片,用 append 扩充切片(对原数组)
slice本身没有数据,是对底层array的一个view
slice的内部:
ptr,指向slice开头的元素,
len,说明slice的长度,方括号取值时只能取到length里面的值,下标超出就报错,
cap(capacity:容量),从ptr开始到结束的整个array的长度;
扩展时,只要不超过capacity就可以扩展,只能向后扩展;
cap(s):slice的容量, len(s):slice的长度
添加元素时如果超过cap,系统会重新分配更大的底层数组
由于是值传递,必须有参数接收append的返回值
s = append(s, val)
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]
7.map
创建时可以先声明再初始化内容
也可以直接初始化
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"] // ok 可以用来判断value存不存在(golang 函数可以有多个返回值)
fmt.Println(r, ok) // 0 false
delete(m, "one")
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)
8.range
对于任意 slice 和 map 可以用 range 来遍历
定义两个变量代表返回索引和值(key和value),省略变量可以用_代替
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
}
}
fmt.Println(sum) // 9
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
for k := range m {
fmt.Println("key", k) // key a; key b
}
9.函数
golang 中函数返回值类型放在后面
函数可以作为参数传递,没有默认参数,可选参数,有变长参数
函数可以返回多个值,可以为返回的多个值起名字
func add(a int, b int) int {
return a + b
}
func add2(a, b int) int {
return a + b
}
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
func main() {
res := add(1, 2)
fmt.Println(res) // 3
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok) // A True
}
10.指针
golang 中指针的作用非常有限,主要是对原数据修改
func add2(n int) {
n += 2
}
func add2ptr(n *int) {
*n += 2
}
func main() {
n := 5
add2(n)
fmt.Println(n) // 5
add2ptr(&n)
fmt.Println(n) // 7
}
11.结构体
具体使用如代码所示
type user struct {
name string
password string
}
func main() {
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"
fmt.Println(a, b, c, d) // {wang 1024} {wang 1024} {wang 1024} {wang 1024}
fmt.Println(checkPassword(a, "haha")) // false
fmt.Println(checkPassword2(&a, "haha")) // false
}
func checkPassword(u user, password string) bool {
return u.password == password
}
func checkPassword2(u *user, password string) bool {
return u.password == password
}
12.结构体方法
为结构体定义方法,可以将普通函数变为类成员函数
具体见代码(注意与上方结构体普通函数进行比较)
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
}
func main() {
a := user{name: "wang", password: "1024"}
a.resetPassword("2048")
fmt.Println(a.checkPassword("2048")) // true
}