我是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
}
}
答案 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完成的代码。这就是并发性。