Golang中的静态全局变量

时间:2018-01-09 16:48:26

标签: go

我是Go语言的新手,我需要一些帮助。我已经声明了一个全局变量,但问题是它没有保留其值。它将通过静态变量解决,但Go中不存在这样的变量。我该怎么解决这个问题? gID是一个全局变量。此函数被调用两次。在第一次通话时如果'代码被执行。在第二个,"否则"代码被执行。我想要第二个struct Learner实例,以获得第一个Learner的实例ID。 我必须提到NewLearner是从两个不同包中的两个不同文件中调用两次

func NewLearner(name string, peerURLs types.URLs, clusterName string, now *time.Time) *Learner {

l := &Learner{
        RaftAttributes: RaftAttributes{PeerURLs: peerURLs.StringSlice()},
        Attributes:     Attributes{Name: name},
    }

    var b []byte
    sort.Strings(l.PeerURLs)
    for _, p := range l.PeerURLs {
        b = append(b, []byte(p)...)
    }

    b = append(b, []byte(clusterName)...)
    if now != nil {
        b = append(b, []byte(fmt.Sprintf("%d", now.Unix()))...)
        hash := sha1.Sum(b)
        l.ID = types.ID(binary.BigEndian.Uint64(hash[:8]))
        gID=l.ID
        return l
    }  else {
        l.ID = gID
        return l    
    }

}

2 个答案:

答案 0 :(得分:0)

包变量不保持其值的事实可能是由并发引起的。 我会这样解决你的问题。如果同时调用该函数,请使用带有互斥锁的包变量。

import "sync"

var(
    gID  uint64
    muID sync.Mutex
)

func myfunc(param bool) {
    var id uint64
    if param {
        id = newID()

        muID.Lock()
        gID = id
        muID.Unlock()
    } else {
        muID.Lock()
        id = gID
        muID.Unlock()
    }
}

答案 1 :(得分:0)

使用频道怎么样?您可以拥有uint64的频道(在您的上下文中为全局)。

idChan := make(chan uint64)

然后在你的if条件中你可以将gID放在idChan中并从你的其他条件中读取相同内容..这样的事情:

if now != nil {
        b = append(b, []byte(fmt.Sprintf("%d", now.Unix()))...)
        hash := sha1.Sum(b)
        l.ID = types.ID(binary.BigEndian.Uint64(hash[:8]))
        idChan <- l.ID
        return l
    }  else {
        l.ID <- idChan
        return l    
    }

请记住,如果您不想在其他任何地方使用它,请适当关闭您的频道。

虽然,我必须建议这些东西通常更好,更安全地处理由waitgroups的例程,因为你实际上想要共享一个值。在你的情况下,可能是一个go例程,如果part和other执行else部分然后在这两个go-routine之间共享此通道并等待等待组依赖于这些goroutine完成的代码。这就是并发性。