go语言学习笔记
开始学习 Golang 的语法。
主要记录 go 和 python 的异同点,随便写写,以供自励。
包管理
同一文件夹下的文件均应属于同一package
,同一包下的文件不需要import
即可直接调用,同一内应有且只有一个main
函数。
只有以大写字母开头的变量/函数/结构体包外可见,包内无影响。
变量类型
基本类型:布尔、整数、浮点、字符串等
引用类型:切片(slice
)、map、接口(interface
)、函数类型(func
)、chan
;引用类型的本质是在传递时传递指针,所以引用中会改变变量原本的值。
需要注意 Go 是强类型语言,且不会做隐形转化,所以0!=false
1 package main
2
3 import (
4 "fmt"
5 "math"
6 "reflect"
7 )
8
9 var a_bool bool // true or false 全局变量声明必须以 var 关键字开头
10 var A_can_be_import bool // 如果想要在外部包中使用全局变量的首字母必须大写
11 var (
12 a_string string
13 a_int int // int8 int16 int32 int64 有符号整数
14 a_uint uint // uint8 uint16 uint32 uint64 无符号整数
15 a_uintprt uintptr // uintptr 无符号整数,容纳指针,仅用于底层编程
16 a_byte byte // byte == uint8
17 a_rune rune // rune == int32 an Unicode code
18 a_float32 float32 // float32 or float64
19 a_pointer *int = &a_int
20 )
21
22 const A_const = 1e11 // 常量
23
24 func b_func() bool {
25 b_bool := false // only inside func
26 return b_bool
27 }
28
29 func main() {
30 var attack = 40 // 局部变量
31 var defence = 20
32 var hitted = false
33 var missed = true
34 var hitormiss bool
35 var hitrate = 0.2
36 hitted = !missed // NOT
37 hitormiss = hitted && missed // AND
38 hitormiss = hitormiss || missed // OR
39 _ = attack & defence // 按位与 _匿名变量,赋值立即丢弃
40 _ = attack | defence // 按位或
41 _ = attack ^ defence // 按位异或
42 _ = attack << 2 // 左移位
43 attack >>= 1 // 右移位
44 attack, defence = defence, attack
45 var hitrate_type = reflect.TypeOf(hitrate) // float64
46 fmt.Println(attack, defence, hitrate_type)
47 fmt.Printf("%.9f\n", math.Pi)
48 }
条件语句
1 package main
2
3 import "fmt"
4
5 func main() {
6 var eatted = false
7 var later = false
8 if eatted {
9 fmt.Println("True")
10 } else if later {
11 fmt.Println("Later")
12 } else {
13 fmt.Println("Not")
14 }
15
16 var a_int = 1
17 switch a_int {
18 case 0:
19 fmt.Println(0)
20 fallthrough // 强制执行下一个case,不会会判断
21 case 1:
22 fmt.Println(1)
23 case 3, 4:
24 fmt.Println(3)
25 default:
26 fmt.Println("Default")
27 }
28
29 switch {
30 case true:
31 fmt.Println("the default switch is true") // true
32 case false:
33 fmt.Println("the default switch is false")
34 }
35 }
循环
1 package main
2
3 import (
4 "fmt"
5 )
6
7 func main() {
8 for true { // true can be omitted
9 fmt.Println("This is a endless loop.")
10 break // break the loop
11 }
12
13 LOOP:
14 for i := 0; i < 10; i++ {
15 if i == 0 {
16 fmt.Println("i==0 continue")
17 continue // skip the rest continue next loop
18 }
19 for j := 0; j <= i; j++ {
20 if j == 0 {
21 continue
22 }
23 fmt.Printf("%d*%d=%d ", j, i, i*j)
24 }
25 fmt.Print("\n")
26 }
27
28 numbers := [5]int{1, 3, 5, 7}
29 for i, x := range numbers {
30 fmt.Printf("the list-%d is %d\n", i, x)
31 }
32
33 goto LOOP // Not recommend
34 }
切片/数组/Map
1 package main
2
3 import (
4 F "fmt"
5 )
6
7 func aSlice() {
8 var aIntSlice []int = make([]int, 5)
9 // or
10 aFloat32Slice := make([]float32, 2)
11 aBoolSlice := []bool{true, false}
12 aFloat64Array := [4]float64{1.1, 2.2}
13 F.Println(
14 aIntSlice,
15 aFloat32Slice,
16 aBoolSlice,
17 aFloat64Array,
18 )
19
20 aDict := make(map[string]int)
21 aDict["a"] = 1
22 // or
23 bDict := map[string]int{"b": 2}
24 F.Println(bDict["c"]) // "c" not exists return 0
25 c, exists := bDict["c"]
26 F.Println(c, exists) // 0 false
27 delete(bDict, "b") // delete "b"
28 F.Println(bDict) // map[]
29 delete(aDict, "b") // no effect
30 F.Println(aDict) // map[a:1]
31 }
切片的底层由数组实现,数组的长度、容量固定,所以无法像Python
一样使用append
方法,切片的长度容量不固定,具有append
方法。
传参时时数组为复制引用,而切片是传递指针,与Map
相同,所以是直接使用。
结构类型
1 package main
2
3 import F "fmt"
4
5 type person struct {
6 name string
7 age int
8 // adult bool = true can't do like this in golang
9 adult bool
10 }
11
12 func (p person) isAdult() string {
13 if p.adult {
14 return p.name + " is adult."
15 } else {
16 return p.name + " is not adult."
17 }
18 }
19
20 func Struct() {
21 var man person
22 var p = NewPerson()
23 Bob := person{"Bob", 20, false} // must had all args
24 // or
25 Alice := person{name: "Alice", age: 30}
26 F.Println(
27 man, // { 0 false}
28 p.name == "", // true
29 Bob, // {Bob 20 false}
30 Alice, // {Alice 30 false}
31 Alice.isAdult(), // Alice is not adult.
32 )
33
34 }
35
36 func NewPerson() person {
37 return person{adult: true}
38 }
结构体同样传递的是复制的值,如果需要传递本身,需要使用其指针。
29 July 2017