Golang 数据类型 声明 1 2 var name type = valuename := value
转换
$\rightarrow string$ 转换
方式一:$fmt.Sprintf()$
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 fmt.Sprintf("%参数" , 表达式) bool %t the word true or false digit %b base 2 %c the character represented by the corresponding Unicode code point %d base 10 %o base 8 %O base 8 with 0 o prefix %q a single-quoted character literal safely escaped with Go syntax. %x base 16 , with lower-case letters for a-f %X base 16 , with upper-case letters for A-F %U Unicode format: U+1234 ; same as "U+%04X" float %b decimalless scientific notation with exponent a power of two, in the manner of strconv.FormatFloat with the 'b' format, e.g. -123456 p-78 %e scientific notation, e.g. -1.234456e+78 %E scientific notation, e.g. -1.234456E+78 %f decimal point but no exponent, e.g. 123.456 %F synonym for %f %g %e for large exponents, %f otherwise. Precision is discussed below. %G %E for large exponents, %F otherwise %x hexadecimal notation (with decimal power of two exponent), e.g. -0x1 .23 abcp+20 %X upper-case hexadecimal notation, e.g. -0X1 .23 ABCP+20
方式二: $strconv$ 包
1 2 strconv.FormatInt(i int64 , base int ) string strconv.FormatFloat(f float64 , fmt byte , prec int , bitSize int ) string
$string \rightarrow$ 转换
1 2 strconv.ParseInt(s string , base int , bitSize int ) (i int64 , err error ) strconv.ParseFloat(s string , bitSize int ) (float64 , error )
切片 动态数组,可修改。
$string$ 是切片,不可修改。
IO 1 2 3 4 5 6 7 8 9 10 11 var name string var age int fmt.Scan(a ...any) (n int , err error ) fmt.Scan(&name, &age) Scanf(format string , a ...any) (n int , err error ) fmt.Scanf("%s%d" , &name, &age) fmt.Scanln(a ...any) (n int , err error ) fmt.Scanln(&name)
流程控制 switch 1 2 3 4 5 6 7 8 9 switch name {case "a" , "A" : fmt.Println("A" ) case "b" , "B" : fmt.Println("B" ) default : fmt.Println("Default" ) }
函数 init
defer 遇到 $defer$ 语句时,将该语句放入栈(相关值直接拷贝 ),在函数返回后 从栈顶开始执行。
遇到 $panic$ 仍然会执行,可以用来 $recover$ ,类似 $try-catch$
1 2 file = openfile(...) defer file.close ()
内置函数 1 2 3 4 5 6 7 8 9 10 append ()len ()copy ()min() max() new ()make ()recover ()delete ()...
错误处理 $defer \rightarrow panic \rightarrow recover$
1 2 3 4 5 6 7 8 9 10 func testError () { defer func () { err := recover () fmt.Println("Error! " , err) }() var a int = 10 var b int = 0 var c int = a / b fmt.Println(c) }
自定义错误类型
1 2 3 4 5 6 7 8 func testError () { defer func () { err := recover () fmt.Println("Error! " , err) }() err := errors.New("something wrong" ) panic (err) }
面向对象 封装 1 2 3 4 5 6 7 8 9 type Person struct { Name string Age int } func (p *Person) Set(name string , age int ) { p.Name = name p.Age = age }
继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type Person struct { Name string Age int } type Student struct { Person major string } type Teacher struct { Person teach string }
接口 $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 42 43 44 45 46 47 48 49 50 51 52 53 type Behavior interface { Say() Walk() } func (s Student) Say() { fmt.Println("Student Say" ) } func (s Student) Walk() { fmt.Println("Student Walk" ) } func (t Teacher) Say() { fmt.Println("Teacher Say" ) } func (t Teacher) Walk() { fmt.Println("Teacher Walk" ) } func TestInterface (b Behavior) { b.Say() b.Walk() } a := Teacher{ Person: Person{ Name: "alice" , Age: 24 , }, teach: "math" , } b := Student{ Person: Person{ Name: "bob" , Age: 18 , }, major: "math" , } TestInterface(a) TestInterface(b) func (p Person) Say() { fmt.Println(p.Name, " Say" ) } func (p Person) Walk() { fmt.Println(p.Name, " Walk" ) }
类型断言 1 2 3 4 5 6 7 8 var i interface {}i = a c, ok := i.(Teacher) if ok { TestInterface(c) } else { fmt.Println("failed" ) }
文件操作 $os$ 内 $File$ 。
1 2 3 4 func Create (name string ) (*File, error )func Open (name string ) (*File, error )func (f *File) Close() error func (f *File) Name() string
$sample$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 file, err := os.Open("data.txt" ) if err != nil { fmt.Println("Open file failed" ) return } defer file.Close()reader := bufio.NewReader(file) for { str, err := reader.ReadString('\n' ) if err == io.EOF { break } if err == nil { fmt.Print(str) } else { fmt.Print(err) } }
JSON 序列化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 func json .Marshal (v any) ([]byte , error )p := Person{ Name: "alice" , Age: 18 , } data, err := json.Marshal(p) if err == nil { fmt.Println(string (data)) } else { fmt.Println(err) } f := make (map [string ]int ) f["score" ] = 100 f["Age" ] = 18 data, err := json.Marshal(f) if err == nil { fmt.Println(string (data)) } else { fmt.Println(err) }
自定义序列化标签
1 2 3 4 type Person struct { Name string `json:"name"` Age int `json:"age"` }
反序列化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 func json .Unmarshal (data []byte , v any) error str := "{\"name\":\"alice\",\"age\":18}" var p Personerr := json.Unmarshal([]byte (str), &p) if err == nil { fmt.Println(p.Name, p.Age) } else { fmt.Println(err) } str := "{\"score\":10,\"age\":18}" p := make (map [string ]int ) err := json.Unmarshal([]byte (str), &p) if err == nil { fmt.Println(p) } else { fmt.Println(err) }
协程 go $go$ 关键字,轻量级线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 func TestRoutine () { for i := 0 ; i < 10 ; i++ { fmt.Printf("SubTask%d\n" , i) time.Sleep(time.Second) } } func main () { go TestRoutine() for i := 0 ; i < 10 ; i++ { fmt.Printf("MainTask%d\n" , i) time.Sleep(time.Second * 2 ) } }
mutex 1 2 3 4 5 6 7 8 9 10 11 12 13 14 var ( fac = make ([]int , 200 ) lk sync.Mutex ) func TestRace (n int ) { res := 1 for i := 1 ; i <= n; i++ { res *= i lk.Lock() fac[i] = res lk.Unlock() } }
channel 协程间通信,本质是队列。
所有协程阻塞会 $dead ; lock$ 。
1 2 3 4 5 6 7 func TestChannel () { var a chan int = make (chan int , 3 ) a <- 10 b := <-a fmt.Println(b) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func TestChannel () { allchan := make (chan interface {}, 10 ) allchan <- 10 allchan <- "bob" allchan <- Person{ Name: "alice" , Age: 18 , } <-allchan <-allchan p := <-allchan fmt.Println(p) p = p.(Person) fmt.Println(p) }
$close$
1 2 func close (c chan <- Type)
遍历 $channel$
1 2 3 4 close (allchan) for v := range allchan { fmt.Println(v) }
协程间通信
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 func writeData (ci chan int ) { fmt.Println("start write" ) for i := 0 ; i < 50 ; i++ { ci <- i fmt.Println("write data" , i) } close (ci) fmt.Println("end write" ) } func readData (ci chan int , cb chan bool ) { fmt.Println("start read" ) for { v, ok := <-ci if !ok { break } fmt.Println("read data" , v) } close (cb) fmt.Println("end read" ) } func main () { ci := make (chan int , 10 ) cb := make (chan bool , 1 ) go writeData(ci) go readData(ci, cb) for { _, ok := <-cb if !ok { break } } }
Reflect 1 2 3 func reflect .TypeOf (i any) reflect.Type func reflect .ValueOf (i any) reflect.Value func (reflect.Type) Kind() reflect.Kind
net Dial 1 func net .Dial (network string , address string ) (net.Conn, error )
1 2 3 4 5 connect, err := net.Dial("tcp" , "127.0.0.1:8080" ) if err != nil { fmt.Println("Dial error: " , err) return }
Write 1 func (net.Conn) Write(b []byte ) (n int , err error )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 reader := bufio.NewReader(os.Stdin) for { line, err := reader.ReadString('\n' ) if err != nil { fmt.Println("ReadString error: " , err) return } n, err := connect.Write([]byte (line)) if err != nil { fmt.Println("connect error: " , err) return } fmt.Printf("send %d bytes data\n" , n) }
Listen 1 func net .Listen (network string , address string ) (net.Listener, error )
1 2 3 4 5 6 listen, err := net.Listen("tcp" , "0.0.0.0:8080" ) if err != nil { fmt.Println("listen err:" , err) return } defer listen.Close()
Accept 1 func (net.Listener) Accept() (net.Conn, error )
1 2 3 4 5 6 7 8 9 10 for { fmt.Println("listening..." ) connect, err := listen.Accept() if err != nil { fmt.Println("listen accept err:" , err) } else { fmt.Println("accept suceessfully:" , connect.RemoteAddr()) } go process(connect) }
Read 1 func (net.Conn) Read(b []byte ) (n int , err error )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 func process (connect net.Conn) { defer connect.Close() for { buf := make ([]byte , 1024 ) n, err := connect.Read(buf) if err != nil { fmt.Println("connect read err:" , err) return } else { fmt.Printf("read %d bytes data" , n) fmt.Println(buf[:n]) } } }
http 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func test (writer http.ResponseWriter, request *http.Request) { _, err := fmt.Fprintln(writer, "Test http" ) if err != nil { fmt.Println("send info error:" , err) } } func main () { http.HandleFunc("/test" , test) err := http.ListenAndServe(":9090" , nil ) if err != nil { fmt.Println("http serve failed:" , err) return } }
std sort 1 2 3 4 5 type Interface interface { Len() int Less(i, j int ) bool Swap(i, j int ) }
Heap 1 2 3 4 5 type Interface interface { sort.Interface Push(x any) Pop() any }
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 type Item struct { value int priority int } type PriorityQueue []Itemfunc (p PriorityQueue) Len() int { return len (p) } func (p PriorityQueue) Swap(i int , j int ) { p[i], p[j] = p[j], p[i] } func (p PriorityQueue) Less(i int , j int ) bool { return p[i].priority < p[j].priority } func (p *PriorityQueue) Push(x any) { *p = append (*p, x.(Item)) } func (p *PriorityQueue) Pop() any { old := *p n := len (old) x := old[n-1 ] *p = old[0 :n-1 ] return x } heap.Init(&que) heap.Push(&que, Item{value: k, priority: 0 }) u := heap.Pop(&que).(Item).value