• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go语言初始化变量的几种方法

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在外部var初始化

package main

import (
    "fmt"
    "time"
)

var startTime = time.Now()

func main() {
    fmt.Println(startTime)
}

在init函数初始化

package main

import (
    "fmt"
    "time"
)

var startTime time.Time

func init() {
    startTime = time.Now()
}

func main() {
    fmt.Println(startTime)
}

在main函数执行自定义初始化函数

package main

import (
    "fmt"
    "time"
)

var startTime time.Time

func initApp() {
    startTime = time.Now()
}

func main() {
    initApp()
    fmt.Println(startTime)
}

延迟加载仅初始化一次(单例)

加锁实现

虽然达到要求了,但是有性能问题,因为每一次请求者要竞争锁才能读取到这个连接
其实创建好连接之后,就不需要锁的保护了


var connMu sync.Mutex
var conn net.Conn

func getConn() net.Conn {
    connMu.Lock()
    defer connMu.Unlock()

    if conn != nil {
        return conn
    }
    conn,_ = net.DialTimeout("tcp","baidu.com:80",10*time.Second)
    return conn
}

func main() {
    conn := getConn()
    if conn != nil {
        panic("conn is nil")
    }
}

标准库Once实现

package main

import (
    "net"
    "sync"
)

var conn net.Conn
var once sync.Once

func getConn() net.Conn {
    var err error
    once.Do(func() {
        conn, err = net.Dial("tcp", "baidu.com")
    })
    return conn
}

func main() {
    conn := getConn()
    if conn != nil {
        panic("conn is nil")
    }
}

自定义Once实现

Once实现的逻辑有一个缺陷,就是当f函数初始化失败后,以后就不会再执行了,我们其实可以在Once里加入当f函数不返回error的时候才代表初始化完成了
另外,我们还可以返回Done检察是否已经初始化完成了

package main

import (
    "errors"
    "fmt"
    "sync"
    "sync/atomic"
)

type Once struct {
    done uint32
    m sync.Mutex
}

func (o *Once) Do(f func() error) error {
    if atomic.LoadUint32(&o.done) == 0 {
        return o.doSlow(f)
    }
    return nil
}

func (o *Once) doSlow(f func() error) (err error) {
    o.m.Lock()
    defer o.m.Unlock()
    if o.done == 0 {
        if err = f(); err == nil {
            defer atomic.StoreUint32(&o.done, 1)
        }
    }
    return err
}
//再加入一个判断Once是否执行完的方法
func (o *Once) Done() bool {
    return atomic.LoadUint32(&o.done) == 1
}

func main() {
    var once Once
    once.Do(func() error {
        fmt.Println("one")
        return errors.New("one error")
    })
    fmt.Println(once.Done())
    once.Do(func() error {
        fmt.Println("two")
        return nil
    })
    fmt.Println(once.Done())
}


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap