Go代码片段

打印

  1. 使用fmt打印结构体。
   import (
   	"fmt"
   )
   
   //打印结构体并输出字段名
   fmt.Printf("%+v", bc)
   //{Id:1 BcId:3 Name:缓存集群 Type:1 Operator:袁青松 Status:1 Ctime:1571197361 Utime:2019-10-16 15:40:55}
   
   //单独使用这个方法会产生一个换行
   fmt.Println()
   
   //打印结构体
   fmt.Printf("%v", bc)
   //{1 3 缓存集群 1 袁青松 1 1571197361 2019-10-16 15:40:55}
   
   //打印结构体的响应go语法表示
   fmt.Printf("%#v", bc)
   //model.BusinessClassification{Id:1, BcId:3, Name:"缓存集群", Type:1, Operator:"袁青松", Status:1, Ctime:1571197361, Utime:"2019-10-16 15:40:55"}
   
   //打印结构体的go类型
   fmt.Printf("%T", bc)
   //model.BusinessClassification

fmt.Print有几个变种:

   > Print:   输出到控制台,不接受任何格式化操作
   > Println: 输出到控制台并换行
   > Printf : 只可以打印出格式化的字符串。只可以直接输出字符串类型的变量(不可以输出别的类型)
   > Sprintf:格式化并返回一个字符串而不带任何输出
   > Fprintf:来格式化并输出到 io.Writers 而不是 os.Stdout
   > ```
   >
   > 通用占位符:
   >
   > ```go
   > %v     值的默认格式。
   > %+v   类似%v,但输出结构体时会添加字段名
   > %#v  相应值的Go语法表示 
   > %T    相应值的类型的Go语法表示 
   > %%    百分号,字面上的%,非占位符含义
   > ```
   >
   > 整数类型:
   >
   > ```go
   > %b     二进制表示 
   > %c     相应Unicode码点所表示的字符 
   > %d     十进制表示 
   > %o     八进制表示 
   > %q     单引号围绕的字符字面值,由Go语法安全地转义 
   > %x     十六进制表示,字母形式为小写 a-f 
   > %X     十六进制表示,字母形式为大写 A-F 
   > %U     Unicode格式:123,等同于 "U+007B"
   > ```
   >
   > 浮点类型:
   >
   > ```go
   > %b    无小数部分、二进制指数的科学计数法,如-123456p-78;
   >      参见strconv.FormatFloat %e    科学计数法,如-1234.456e+78 %E    
   >      科学计数法,如-1234.456E+78 %f    
   >      有小数部分但无指数部分,如123.456 %F    等价于%f %g    
   >      根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
   >      
   > %e     科学计数法,例如 -1234.456e+78 
   > %E     科学计数法,例如 -1234.456E+78 
   > %f     有小数点而无指数,例如 123.456 
   > %g     根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的0)输出 
   > %G     根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的0)输出
   > ```
   >
   > 布尔型:
   >
   > ```go
   > %t   true 或 false
   > ```
   >
   > 字符串类型:
   >
   > ```go
   > %s     字符串或切片的无解译字节 
   > %q     双引号围绕的字符串,由Go语法安全地转义 
   > %x     十六进制,用小写字母表示,每字节两个字符 
   > %X     十六进制,用大写字母表示,每字节两个字符
   > ```
   >
   > 指针类型:
   >
   > ```go
   > %p     十六进制表示,输出内存地址,前缀 0x
   > ```
   
2. 打印变量类型。
   
   ```go
   import (
   	"fmt"
       "reflect"
   )
   
   fmt.Println(reflect.TypeOf(var)) 

Redis

MySQL

  1. 连接数据库。sql.Open方法只创建数据库抽象,不是数据库连接。它维护着一个连接池。当连接建立后才创建连接池,这儿通过ping方法建立连接。
   import (
       "database/sql"
       _ "github.com/go-sql-driver/mysql"
   )
   
   db, _ := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/test?charset=utf8")
   db.SetMaxOpenConns(2000)
   db.SetMaxIdleConns(1000)
   db.SetConnMaxLifetime(time.Second * time.Duration(3600))
   db.Ping()//Ping方法返回err

字符串

  1. 字符串转数字。
   import (
       "strconv"
   )
   
   //转为int64的,func ParseInt(s string, base int, bitSize int) (i int64, err error)
   //三个参数分别是字符串,进制,返回结果位数
   //第三位有效值为0、8、16、32、64,0表示int/uint,8表示int8/uint8,只限制返回值的取值范围。
   i, _ := strconv.ParseInt("123", 10, 32)
   j, _ := strconv.ParseUint("123", 10, 32)
   
   //转为int的,func Atoi(s string) (int, error)
   i,_ := strconv.Atoi("3")
  1. 数字转字符串。
   import (
       "strconv"
   )
   
   //int转字符串
   println("a" + strconv.Itoa(32))
   
   //int64转字符串,func FormatInt(i int64, base int) string
   //func FormatUint(i uint64, base int) string
   //第二个参数指定进制
   s := strconv.FormatInt(-42, 16)
   
  1. 字符串拼接。
   import (
       "strings"
       "fmt"
   )
   
   var b strings.Builder
   b.WriteString("abc")
   b.WriteString("\n")
   fmt.Println(b.String())

数组

错误

  1. 自定义错误。
   import (
       "errors"
   )
   
   errors.New("错误说明")

时间

  1. 休眠一段时间
   import (
       "time"
   )
   time.Sleep(time.Second)

系统

  1. 系统信号处理,可以处理term信号发送时,系统在退出前的一系列动作等。
   package main
   
   import (
       "fmt"
       "os"
       "os/signal"
   )
   
   func main() {
       c := make(chan os.Signal) //监听所有信号
       signal.Notify(c)          //阻塞直到有信号传入,后面的参数可以设置为指定的信号类型
       						  //如syscall.SIGHUP
   							  //func Notify(c chan<- os.Signal, sig ...os.Signal)
       fmt.Println("启动")
       s := <-c
       fmt.Println("退出信号", s)
   }
  1. 调用系统方法。读取系统返回并逐行处理。
   import (
       "io/ioutil"
       "os/exec"
       "bufio"
   )
   
   cmd := exec.Command("ls", "-a", "-l")
   stdout, _ := cmd.StdoutPipe() //标准输出
   _ = cmd.Start()
   
   outputBuf := bufio.NewReader(stdout)                                        
   var ret strings.Builder                                                     
   for {                                                                       
       output, _, err := outputBuf.ReadLine()                                  
       if err != nil {                                                         
       	if err.Error() != "EOF" {                                             
           	//something to do                                                    
           }  else {
               break 
           }                     
       }                                                                       
       res := string(output)                                                   
   	//something to do                                                                
   	ret.WriteString(res + "\n")                                        
   }                                                                           
                                                                                  
   if err := cmd.Wait(); err != nil {                                          
   	//something to do                                
   }           
   fmt.Println(ret.String())

管道

  1. 配合select设置超时时间。
   ch := make(chan struct{})
   
   go doTask(ch)
   
   timeout := time.After(5 * time.Second)
   select {
       case <- ch:
           fmt.Println("task finished.")
       case <- timeout:
           fmt.Println("task timeout.")
   }
   //在select中可以同时监听多个chan返回。
   //若只有一个chann返回则执行这个,多个返回则随机选择一个执行
   //若所有的chann都阻塞,且又定义了default,则执行default,否则一直阻塞
   //使用break跳出
  1. 配合select实现终止常驻任务。
   g := make(chan int)
   quit := make(chan bool)
   
   go func() {
       outLable:
           for {
               select {
               case v := <-g:
                   fmt.Println(v)
               case <-quit:
                   fmt.Println("B退出")
                   break outLable //这儿如果不用标签,则只会跳出select,不会跳出for循环
                                  //或者使用return跳出
               }
           }
   }()
   
   for i := 0; i < 3; i++ {
   	g <- i
   }
   quit <- true
   fmt.Println("testAB退出")
  1. 关闭管道,关闭两次或者在关闭后写入会导致panic。但是可以在关闭后读取,来判断是否已经关闭。
   import (
       "fmt"
   )
   
   c := make(chan int, 1)
   c <- 1
   close(c) //一个原则是不能在接收端关闭管道
   for {
       i, ok := <-c //用判断是否已经关闭了
       if !ok { //已经关闭了,如果是没有关闭可以再次close管道
           fmt.Println("channel closed!")
           break
       }
       fmt.Println(i)
   }

← 架构修炼之道读书笔记  深入理解Nginx读书笔记 →