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