Go语言极速入门手册.go

jopen 5年前

Github: https://github.com/coderzh/CodeTips

/*  gotips_test.go:    Golang速学速查速用代码手册    Source: github.com/coderzh/CodeTips/blob/master/gotips_test.go    Author: coderzh(github.com/coderzh)  Blog: http://blog.coderzh.com  参考:《Go语言编程》  */    package main    import (      "errors"      "fmt"      "github.com/stretchr/testify/assert"      "io"      "io/ioutil"      "log"      "math"      "os"      "path/filepath"      "regexp"      "strings"      "sync"      "testing"      "time"  )    // 0. 注释  /*  规范:   1. 命名:骆驼命名法(不要用下划线)    命令:   go get github.com/coderzh/xxx   go build calc   go run xxx.go   go install calc  */    // 1. Hello World  func helloWorld() {      fmt.Println("Hello, 世界")  }    // 2.变量类型  func typeDemo() {      // 变量声明      var v1 int      var (          v2 int          v3 string      )      //var p *int // 指针类型        // 变量初始化      var v4 int = 10      // 等价于:      var v5 = 10      // 一般这样就好      v6 := 10        // 赋值,多重赋值      v1 = 10      v2, v3 = 20, "test"      // 匿名变量 _      _, v4 = v5, v6        fmt.Println(v1, v2, v3, v4)        // 常量      const Pi float64 = 3.1415926      const MaxPlayer = 10        // 枚举      const (          Sunday = iota // iota从0递增          Mondy          Tuesday          // ...      )        // 类型      // 1. 布尔      var b1 bool      b1 = true      b1 = (1 == 2)        fmt.Println(b1)        // 2. 整形      // int8 uint8 int16 uint16 int32 uint32 int64 uint64 int uint uintptr      var i32 int32      // 强制转换      i32 = int32(64)      // 运算:+, -, *, /, %(求余)      // 比较:>, <, ==, >=, <=, !=      // 位运算:x << y, x >> y, x ^ y, x & y, x | y, ^x (取反)        fmt.Println(i32)        // 3. 浮点      // float32, float64      var f1 float64 = 1.0001      var f2 float64 = 1.0002      // 浮点比较      isEqual := math.Dim(f1, f2) < 0.0001        fmt.Println(isEqual)        // 4. 字符串      var s1 string      s1 = "abc"      // 字符串连接      s1 = s1 + "ddd"      // 取长度      n := len(s1)      // 取字符      c1 := s1[0]      // 反引号,不转义,常用于正则表达式      s1 = `\w+`        fmt.Println(c1)        fmt.Println(strings.HasPrefix("prefix", "pre")) // true      fmt.Println(strings.HasSuffix("suffix", "fix")) // true        // 字节遍历      for i := 0; i < n; i++ {          ch := s1[i]          fmt.Println(ch)      }      // Unicode字符遍历      for i, ch := range s1 {          fmt.Println(i, ch)      }        // 5. 数组      var arr1 [32]int      //var arr2 [3][8]int // 二维数组      // 初始化      arr1 = [32]int{0}      array := [5]int{1, 2, 3, 4, 5}      // 临时结构体数组      structArray := []struct {          name string          age  int      }{{"Tim", 18}, {"Jim", 20}}        // 数组遍历      for i := 0; i < len(array); i++ {          fmt.Println(array[i])      }      for i, v := range structArray {          fmt.Println(i, v)      }      // 数组是值类型,每次参数传递都是一份拷贝        // 数组切片Slice      var mySlice []int = arr1[:2]      mySlice1 := make([]int, 5)      mySlice2 := make([]int, 5, 10)        fmt.Println("len(mySlice2:", len(mySlice2)) // 5      fmt.Println("cap(mySlice2:", cap(mySlice2)) // 10        mySlice3 := append(mySlice, 2, 3, 4)      mySlice4 := append(mySlice, mySlice1...)        copy(mySlice3, mySlice4)        // 6. Map      var m map[int]string      m[1] = "ddd"      m1 := make(map[int]string)      m2 := map[int]string{          1: "a",          2: "b",      }        delete(m2, 1)        value, ok := m1[1]      if ok {          fmt.Println(value)      }        for k, v := range m2 {          fmt.Println(k, v)      }    }    // 3. 流程控制  func flowDemo() {      // if else      a := 10      if a < 10 {          // ..      } else {          // ..      }        // switch      switch a {      case 0:          fmt.Println("0")      case 10:          fmt.Println("10")      default:          fmt.Println("default")      }        switch {      case a < 10:          fmt.Println("<10")      case a < 20:          fmt.Println("<20")      }        // 循环      for i := 0; i < 10; i++ {      }      // 无限循环      sum := 0      for {          sum++          if sum > 10 {              break              // 指定break              // break JLoop          }      }        goto JLoop    JLoop:      // break to here    }    // 4. 函数  // func 函数名(参数列表)(返回值列表) {  // }  func sum1(value1 int, value2 int) (result int, err error) {      // err = errors.New("xxxx")      return value1 + value2, nil  }    func sum2(value1, value2 int) int {      return value1 + value2  }    // 不定参数  // myFunc(1, 2, 3, 4, 5)  func myFunc(args ...int) {      for _, arg := range args {          fmt.Println(arg)      }      // 传递      // myFunc2(args...)      // myFunc2(args[1:]...)  }    // 任意类型的不定参数  func myPrintf(args ...interface{}) {      for _, arg := range args {          switch arg.(type) {          case int:              fmt.Println(arg, "is int")          case string:              fmt.Println(arg, "is string")          default:              fmt.Println(arg, "is unknown")          }      }  }    // 匿名函数  func anonymousFunc() {      f := func(a, b int) int {          return a + b      }        f(1, 2)  }    // defer  func deferDemo(path string) {      f, err := os.Open(path)      if err != nil {          return      }        defer f.Close()      // or      defer func() {          if r := recover(); r != nil {              fmt.Printf("Runtime error caught: %v", r)          }      }()  }    // 5. 结构体  type Rect struct {      // 小写为private      x, y float64      // 大写为public      Width, Height float64  }    // 大写方法为public,小写为private  func (r *Rect) Area() float64 {      return r.Width * r.Height  }    func netRect(x, y, width, height float64) *Rect {      // 实例化结构体      // rect1 := new(Rect)      // rect2 := &Rect{}      // rect3 := &Rect{Width:100, Height:200}      return &Rect{x, y, width, height}  }    // 匿名组合  type Base struct {      Name string  }    func (base *Base) Foo() {}  func (base *Base) Bar() {}    type Foo struct {      Base      *log.Logger  }    func (foo *Foo) Bar() {      foo.Base.Bar()      // ...  }    // 非侵入式接口  type IFile interface {      Read(buf []byte) (n int, err error)      Write(buf []byte) (n int, err error)  }    type File struct {  }    func (file *File) Read(buf []byte) (n int, err error) {      return 0, nil  }    func (file *File) Write(buf []byte) (n int, err error) {      return 0, nil  }    func interfaceDemo() {      // 只要实现了Read, Write方法即可      var file IFile = new(File)        // 接口查询      // 是否实现了IFile接口      if file2, ok := file.(IFile); ok {          file2.Read([]byte{})      }      // 实例类型是否是File      if file3, ok := file.(*File); ok {          file3.Read([]byte{})      }        // 类型查询      switch v := file.(type) {      }  }    // 6. 并发编程  func counting(ch chan int) {      ch <- 1      fmt.Println("counting")  }    func channelDemo() {      chs := make([]chan int, 10)      for i := 0; i < len(chs); i++ {          chs[i] = make(chan int)          // 带缓冲区大小          // c: = make(chan int, 1024)          // for i:= range c {          // }          go counting(chs[i])      }        for _, ch := range chs {          <-ch          // channel select          /*              select {              case <-ch:                  // ...              case ch <- 1:              }          */      }        // 单向Channel      var ch1 chan<- int // 只能写入int      var ch2 <-chan int // 只能读出int        // 关闭Channel      close(ch1)      _, ok := <-ch2      if !ok {          // already closed      }  }    // 锁  var m sync.Mutex    func lockDemo() {      m.Lock()      // do something      defer m.Unlock()  }    // 全局唯一操作  var once sync.Once    // once.Do(someFunction)    // 7. 网络编程  // import "net"  // net.Dial("tcp", "127.0.0.1:8080")    // 8. json处理  // import "encoding/json"  // json.Marshal(obj) 序列化  // json.Unmarshal() 反序列化    // 9. Web开发  // import "net/http"  // 模板  // import "html/template"    // 10. 常用库  // import "os"  // import "io"  // import "flag"  // import "strconv"  // import "crypto/sha1"  // import "crypto/md5"    // 11. 单元测试  // _test结尾的go文件: xxx_test.go  // 函数名以Test开头  func TestDemo(t *testing.T) {      r := sum2(2, 3)      if r != 5 {          t.Errorf("sum2(2, 3) failed. Got %d, expect 5.", r)      }        assert.Equal(t, 1, 1)  }    // 12. 性能测试  func benchmarkAdd(b *testing.B) {      b.StopTimer()      // dosometing      b.StartTimer()  }    /*   其他常用的代码片段  */    // 1. 遍历文件 filepath.Walk  // import "path/filepath"  func doHashWalk(dirPath string) error {        fullPath, err := filepath.Abs(dirPath)        if err != nil {          return err      }        callback := func(path string, fi os.FileInfo, err error) error {          return hashFile(fullPath, path, fi, err)      }        return filepath.Walk(fullPath, callback)  }    func hashFile(root string, path string, fi os.FileInfo, err error) error {      if fi.IsDir() {          return nil      }      rel, err := filepath.Rel(root, path)      if err != nil {          return err      }      log.Println("hash rel:", rel, "abs:", path)      return nil  }    // 2. 读取文件  // import "io/ioutil"  func readFileDemo(filename string) {      content, err := ioutil.ReadFile(filename)      if err != nil {          //Do something      }      lines := strings.Split(string(content), "\n")      fmt.Println("line count:", len(lines))  }    // 判断目录或文件是否存在  func existsPathCheck(path string) (bool, error) {      // 判断不存在      if _, err := os.Stat(path); os.IsNotExist(err) {          // 不存在      }        // 判断是否存在      _, err := os.Stat(path)      if err == nil {          return true, nil      }      if os.IsNotExist(err) {          return false, nil      }      return true, err  }    // 文件目录操作  func fileDirDemo() {      // 级联创建目录      os.MkdirAll("/path/to/create", 0777)  }    // 拷贝文件  func copyFile(source string, dest string) (err error) {      sf, err := os.Open(source)      if err != nil {          return err      }      defer sf.Close()      df, err := os.Create(dest)      if err != nil {          return err      }      defer df.Close()      _, err = io.Copy(df, sf)      if err == nil {          si, err := os.Stat(source)          if err != nil {              err = os.Chmod(dest, si.Mode())          }        }      return  }    // 拷贝目录  func copyDir(source string, dest string) (err error) {      fi, err := os.Stat(source)      if err != nil {          return err      }      if !fi.IsDir() {          return errors.New(source + " is not a directory")      }      err = os.MkdirAll(dest, fi.Mode())      if err != nil {          return err      }      entries, err := ioutil.ReadDir(source)      for _, entry := range entries {          sfp := filepath.Join(source, entry.Name())          dfp := filepath.Join(dest, entry.Name())          if entry.IsDir() {              err = copyDir(sfp, dfp)              if err != nil {                  fmt.Println(err)              }          } else {              err = copyFile(sfp, dfp)              if err != nil {                  fmt.Println(err)              }          }        }      return nil  }    // 3. 时间处理  // import "time"  func TestTimeDemo(t *testing.T) {      // Parse      postDate, err := time.Parse("2006-01-02 15:04:05", "2015-09-30 19:19:00")      fmt.Println(postDate, err)        // Format      assert.Equal(t, "2015/Sep/30 07:19:00", postDate.Format("2006/Jan/02 03:04:05"))      assert.Equal(t, "2015-09-30T19:19:00Z", postDate.Format(time.RFC3339))  }    // 4. 正则表达式  // import "regexp"  func TestRegexp(t *testing.T) {      // 查找匹配      re := regexp.MustCompile(`(\d+)-(\d+)`)      r := re.FindAllStringSubmatch("123-666", -1)        assert.Equal(t, 1, len(r))      assert.Equal(t, "123", r[0][1])      assert.Equal(t, "666", r[0][2])    }    func main() {      helloWorld()  }

来自:http://blog.coderzh.com/2015/09/28/go-tips/