打印

  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
    

    通用占位符:

    %v     值的默认格式
    %+v   类似%v但输出结构体时会添加字段名
    %#v  相应值的Go语法表示 
    %T    相应值的类型的Go语法表示 
    %%    百分号,字面上的%,非占位符含义
    

    整数类型:

    %b     二进制表示 
    %c     相应Unicode码点所表示的字符 
    %d     十进制表示 
    %o     八进制表示 
    %q     单引号围绕的字符字面值由Go语法安全地转义 
    %x     十六进制表示字母形式为小写 a-f 
    %X     十六进制表示字母形式为大写 A-F 
    %U     Unicode格式123等同于 "U+007B"
    

    浮点类型:

    %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输出
    

    布尔型:

    %t   true  false
    

    字符串类型:

    %s     字符串或切片的无解译字节 
    %q     双引号围绕的字符串由Go语法安全地转义 
    %x     十六进制用小写字母表示每字节两个字符 
    %X     十六进制用大写字母表示每字节两个字符
    

    指针类型:

    %p     十六进制表示输出内存地址前缀 0x
    
  2. 打印变量类型。

    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")
    
  2. 数字转字符串。

    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)
    
  3. 字符串拼接。

    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)
    }
    
  2. 调用系统方法。读取系统返回并逐行处理。

    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跳出
    
  2. 配合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退出")
    
  3. 关闭管道,关闭两次或者在关闭后写入会导致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)
    }