[TOC]

go控制语句

if

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

switch

  • fallthrough: 划过执行下一个case
switch var1 {
  case value1:  // do sth
  case value2: 
  	fallthrough // do next case
  case value3:
  	// so sth
  default: 
  	...
}

for

// 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

// 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

var myName string
var myAge int
var isBoy bool

var Name string = superman

constants

const constName type

array and slice

var arrName []type


var studentsName []string

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

make and new

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

map

var mapName map[keyType]valueType

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

struct

type MyType struct{
  Name string
}

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

函数

main

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

package main

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

init

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

return

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

args

函数支持可变长度参数

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: 操作复数

方法

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

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

接口

go语言比较新颖的interface

type interfaceName interface{
  Method1(param_list) return_type
}
  • struct 无需显示声明interface,只需直接实现方法
  • struct除实现interface外,还可以有额外的方法
  • 一个类型可以实现多个接口
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() 返回被检查对象的值
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编解码

// 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

函数退出前执行某个语句

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:

# ./main
loopFunc: 2
loopFunc: 0
loopFunc: 1
3
2
1

panic and recover

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

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

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")

}