Go

  • Golang 中 Goroutine 的调度器模型

    2018-07-24 18:35:36 1387 0 技术文章

    Goroutine 可以说是 Golang 最大的特色

  • Go 语言的 Goroutine 和 channel

    2018-07-13 17:50:27 1529 0 技术文章

    进程,线程的概念在操作系统的书上已经有详细的介绍。进程是内存资源管理和cpu调度的执行单元。为了有效利用多核处理器的优势,将进程进一步细分,允许一个进程里存在多个线程,这多个线程还是共享同一片内存空间,但cpu调度的最小单元变成了线程。

    那协程又是什么东西,以及与线程的差异性??

    协程,可以看作是轻量级的线程。但与线程不同的是,线程的切换是由操作系统控制的,而协程的切换则是由用户控制的。

  • Go 语言中 json 的操作以及常见问题

    2018-06-16 17:04:16 1665 1 技术文章

    常见问题

    结构体里的字段首字母必须大写

    type Person struct{
        Name string
        Age int
    }
    
    func main(){
      person := Person{"小明",18}
      if result, err := json.Marshal(&person);err == nil {
        fmt.Println(string(result))
      }
    }
    

    控制台输出:{"Name":"小明","Age":18}

    如果字段首字母为小写的话,解析会有问题,得到的值为空。

    可以通过字段的 tag 指定 struct 转 json 后的首字母小写

    type Person struct {
        Name string `json:"name"`    
        Age int `json:"age"`
        Time int64 `json:"-"` // 忽略字段
    }
    
    func main(){
      person:=Person{"小明",18, time.Now().Unix()}
      if result,err:=json.Marshal(&person);err==nil{
         fmt.Println(string(result))
      }
    }
    

    控制台输出:{"name":"小明","age":18}

  • Go 语言的面向对象使用场景

    2018-06-13 18:42:25 1525 0 技术文章

    目前大部分高级语言都支持面向对象,比如 C++, JAVA, PHP 等,那么 Go 语言的面向对象怎么使用? 下面我们从面向对象的三个基本特性说起:封装、继承和多态。

    封装,就是指运行的数据和函数绑定在一起,C++ 中主要是通过 this 指针来完成的; 继承,就是指 class 之间可以相互继承属性和函数; 多态,主要就是用统一的接口来处理通用的逻辑,每个 class 只需要按照接口实现自己的回调函数就可以了。

    封装

    package main
    
    import "fmt"
     
    type data struct {
        val int
    }
    
    func (p_data* data)set(num int) {
        p_data.val = num
    }
    
    func (p_data* data)show() {
        fmt.Println(p_data.val)
    }
    
    func main() {
        p_data := &data{4}
        p_data.set(5)
        p_data.show()
    }
    

    继承

    package main
     
    import "fmt"
     
    type parent struct {
        val int
    }
     
    type child struct {
        parent
        num int
    }
     
     
    func main() {
        var c child
     
        c = child{parent{1}, 2}
        fmt.Println(c.num)
        fmt.Println(c.val)
    }
    

    多态

    package main
    
    import "fmt"
    
    type act interface {
        write()
    }
     
    type xiaoming struct {
    }
    
    type xiaofang struct {
    }
    
    func (xm *xiaoming) write() {
        fmt.Println("xiaoming write")
    }
     
    func (xf *xiaofang) write() {
        fmt.Println("xiaofang write")
    }
    
    func main() {
        var w act;
    
        xm := xiaoming{}
        xf := xiaofang{}
    
        w = &xm
        w.write()
    
        w = &xf
        w.write()
    }
    

    以下就是 Go 语言的面向对象的使用方法。使用上比 C++ 表现得更加简洁和直接。

  • Go 语言中使用 defer 的几个场景

    2018-05-20 15:04:16 1402 0 技术文章

    简化资源回收,相当于析构函数

    在 Go 语言中,没有析构函数,如果需要在实例完成后进行资源回收的情况,可以使用 defer 语句。 defer 是先进后出,这样做很合理,后面的语句会依赖前面的资源,如果先前面的资源先释放了,那后面的语句就没法执行了。 当然, defer 也有一定的开销, 也有为了节省性能而回避使用的 defer 的。 使用示例:

    func set(mu *sync.Mutex, i int) {
        mu.Lock()
        mu.Unlock()
    }
    

    panic 异常捕获,recover 只能在 defer 语句中使用

    使用方法如下:

    func main() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println(r)
            }
        }()
        panic("Error")
    }
    

    修改返回值,适用于特定场景

    func doubleSum(a, b int) (sum int) {
        defer func() {
            sum *= 2
        }()
        sum = a + b
    }
    

    安全回收资源,即使 panic 抛出异常,recover 也可捕获

    不使用 defer 的情况,前面的语句出现异常,后面的语句就没有机会执行。

    func set(mu *sync.Mutex, i, v int) {
        mu.Lock()
        i := v / 0 // 0 不能做除数,会抛出异常,后面的语句不能被执行
        mu.Unlock()
    }
    

    使用 defer 的情况,即使前面出现异常,后面的语句照样可以执行。

    func set(mu *sync.Mutex, i, v int) {
        mu.Lock()
        i := v / 0 // 0 不能做除数,会抛出异常,后面的语句不能被执行
        mu.Unlock()
    }
    
  • 使用 go 命令升级至 go1.9beta2

    2017-08-14 09:55:50 2450 0 技术文章

    从 go1.9beta2 运行 go 命令。

    若要安装 go1.9beta2,请运行:

    $ go get golang.org/x/build/version/go1.9beta2
    $ go1.9beta2 download