Go基础使用

[TOC]

go控制语句

if

  • 基本形式
1
2
3
4
5
6
7
8
// 大括号的左边必须跟在语句的后面
if condition1 {
// do something
} else if condition2 {
// do something
} else {
// catch-all or default
}
  • 简短语句
1
2
3
4
// 处理完分号“;”前面的语句之后,再做判断
if v:=x-100; v<0 {
// do something
}

switch

  • fallthrough: 划过执行下一个case
1
2
3
4
5
6
7
8
9
10
switch var1 {
case value1: // do sth
case value2:
fallthrough // do next case
case value3:
// so sth
default:
...
}

for

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// eg 1
for i:=0; i<10; i++ {
sum += i
}

// eg 2
for ; sum < 1000; {
sum += sum
}

// always loop
for {
// do something

if condition {
break
}
}

for range

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// string
for index,char := range myString {
// do something
}

// map
for k,v := range myMap {
// do
}

// array or slice
for index,value := range myArray {
// do
}

数据结构

variable

var varName type

1
2
3
4
5
6
var myName string
var myAge int
var isBoy bool

var Name string = superman

constants

const constName type

array and slice

var arrName []type

1
2
3
4
5
6

var studentsName []string

myArray := [5]int{1,2,3,4,5}
mySlice := myArray[2:4]

make and new

  • new 返回指针地址
  • make返回第一个元素
    • make([]type,[length],[cap])
1
2
3
4
mySlice1 := new([]int)
mySlice2 := make([]int,0)
mySlice2 := make([]int,0,10)
mySlice2 := make([]int,0,10,20)

map

var mapName map[keyType]valueType

1
2
myMap := make(map[string]string, 10)
myMap["a"] = "b"

struct

1
2
3
4
5
6
7
type MyType struct{
Name string
}

func printMyType(t *MyType){
println(t.Name)
}

函数

main

每个go语言程序都应该有一个main package,里面的main函数就是go语言程序的入口。

1
2
3
4
5
package main

func main(){
print("hello world.")
}

init

  • init 函数会在包初始化时运行。类似python里面class中的init函数

return

  • return: 函数可以返回任意数量的返回值,忽略部分用“_”即可,同python

args

函数支持可变长度参数

1
2
3
4
5
6
7
8
func append(slice []Type, elems ...Type) []Type {
// do sth
}

// use it
myArray := []string{}
myArray = append(myArray, "a", "B", "c", "d")

内置函数

  • close
  • len
  • cap: 计算array, slice, map的容量
  • copy, append
  • panic, recover
  • print, println
  • complex, real, imag: 操作复数

方法

上面的例子中已经有示例了

1
2
3
func(recv receiver_type) methodName(parameter_list) (return_value_list) {
// do sth
}

接口

go语言比较新颖的interface

1
2
3
type interfaceName interface{
Method1(param_list) return_type
}
  • struct 无需显示声明interface,只需直接实现方法
  • struct除实现interface外,还可以有额外的方法
  • 一个类型可以实现多个接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import "fmt"

type IF interface{
getName() string
}

type Human struct{
firstName, lastName string
}

func(h *Human) getName() string{
return h.firstName + "," + h.lastName
}

type Car struct{
factory, model string
}

func(c *Car) getName() string{
return c.factory + "," + d.model
}

func main(){
interface := []IF{}

h:=new(Human)
h.firstName = "first"
h.lastName = "last"
interfaces = append(interfaces, h)

c := new(Car)
c.factory = "benz"
c.model = "s"
interfaces = append(interfaces, c)

for _,f := range interfaces{
fmt.Println(f.getName())
}
}

其他

reflect

  • reflect.TypeOf() 返回被检查对象的类型
  • reflect.ValueOf() 返回被检查对象的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import (
"fmt"
"reflect"
)

func main() {
// basic type
myMap := make(map[string]string, 10)
myMap["a"] = "b"
t := reflect.TypeOf(myMap)
fmt.Println("type:", t)
v := reflect.ValueOf(myMap)
fmt.Println("value:", v)
// struct
myStruct := T{A: "a"}
v1 := reflect.ValueOf(myStruct)
for i := 0; i < v1.NumField(); i++ {
fmt.Printf("Field %d: %v\n", i, v1.Field(i))
}
for i := 0; i < v1.NumMethod(); i++ {
fmt.Printf("Method %d: %v\n", i, v1.Method(i))
}
// 需要注意receive是struct还是指针
result := v1.Method(0).Call(nil)
fmt.Println("result:", result)
}

type T struct {
A string
}

// 需要注意receive是struct还是指针
func (t T) String() string {
return t.A + "1"
}

json编解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// from string to struct
func unmarshal2Struct(humanStr string) Human{
h := Human{}
err := json.Unmarshal([]byte(humanStr), &h)
if err != nil{
println(err)
}
return h
}

// from struct to string
func marshal2JsonString(h Human) string{
h.Age = 30
updatedBytes, err := json.Marshal(&h)
if err != nil{
println(err)
}
return string(updatedBytes)
}

defer

函数退出前执行某个语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import (
"fmt"
"sync"
"time"
)

func main() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
loopFunc()
time.Sleep(time.Second)
}

func loopFunc() {
lock := sync.Mutex{}
for i := 0; i < 3; i++ {
go func(i int) {
lock.Lock()
defer lock.Unlock()
fmt.Println("loopFunc:", i)
}(i)
}
}

output:

1
2
3
4
5
6
7
8
# ./main
loopFunc: 2
loopFunc: 0
loopFunc: 1
3
2
1

panic and recover

  • panic: 在系统出现不可恢复错误时主动调用panic,当前线程直接crash
  • defer: 保证defer的代码执行,而后并把控制权交还给接收到panic的函数调用者
  • recover: 函数从panic或者错误场景中恢复

通过再 defer的代码中执行recover,使得panic的内容得到了处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
)

func main() {
defer func() {
fmt.Println("defer func is called")
if err := recover(); err != nil {
fmt.Println(err)
}
}()
panic("a panic is triggered")

}