• Go语言极速入门手册.go


    golang

    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), "
    ")
        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()
    }
    

      

    微信扫一扫交流

    作者:CoderZh 
    微信关注:hacker-thinking (一个程序员的思考) 
    本文出处:https://blog.coderzh.com/2015/09/28/go-tips/ 
    文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利

  • 相关阅读:
    如何制作a2sd+
    WinForm/Silverlight多线程编程中如何更新UI控件的值
    c#如何操作cookie
    Windows Mobile CookieContainer
    Microsoft.Practices.EnterpriseLibrary.Data 数据库操作
    获取手机卡imei和imsi信息
    winform 分页控件
    asp.net 导出数据到Excle
    asp.net异步调用
    shell脚本中常用命令
  • 原文地址:https://www.cnblogs.com/steve-jiang/p/8572163.html
Copyright © 2020-2023  润新知