Go语言:全局变量

7

我可以通过在任何函数外定义对象来轻松地使对象成为全局变量,但是对于必须创建的某些结构体,这种方法不适用。

我要做的事情比这要复杂得多:

package main
import "regexp"

func doSomething(test []byte) []byte {
   test = reg.ReplaceAll(test,nil)
   return test
}

reg, _ := regexp.Compile(`[^a-z\s]`) // this is the issue

func main() {
   thing := doSomething("somebytes")
}

显然,上述方法是不被允许的,但这正是我想要做的。

在不传递对象的情况下,似乎没有任何方法可以使reg对象从doSomething函数中访问,这正是我要避免的,因为我将要执行数十亿次。

如果我把它放在main()中,那么它就不再是全局的了。我甚至尝试过这样做:

var reg regexp.Regexp
func main() {
   reg, _ = regexp.Compile(`[^a-z\s]`)
   thing := doSomething("somebytes")
}

......但那也不起作用,它给了我一个错误。

有什么想法吗?

更新:我的问题实际上并不是与正则表达式有关。那只是一个例子。

2个回答

12

完全允许,你可以使用:

var reg = regexp.MustCompile(`[^a-z\s]`) //or even
var reg, _ = regexp.Compile(`[^a-z\s]`) // MustCompile is the better choice though.

请记住,regexp.Compile / regexp.MustCompile 返回一个指针,这就是为什么您的第二次尝试没有成功,您将*regexp.Regexp 赋值给了 regexp.Regexp

完整的示例

func doSomething(test []byte) []byte {
    test = reg.ReplaceAll(test, nil)
    return test
}

var (
    reg, _ = regexp.Compile(`[^a-z\s]`)
    reg2   *regexp.Regexp
)

func init() { //different way of initializing global valuables
    reg2 = regexp.MustCompile(`[^a-z\s]`)
}

func main() {
    thing := doSomething([]byte("somebytes"))
    fmt.Println(thing)
}

1
太好了。显然我还没有掌握这个技巧。这是我没有想到尝试的一件事。等系统允许时,我会接受你的答案。谢谢! - Alasdair
我添加了一个完整的示例,并解释了为什么你的第二次尝试没有成功。 - OneOfOne
使用全局变量可能会被视为不利的(即“名称空间污染”)。如果你的问题是关于在不同函数之间传递变量时总是进行复制,那么在函数调用中使用指针将避免这种复制。 - ABri
1
除非将名称大写,否则它不是Go语言中的私有变量,而是特定包中的私有变量。 - OneOfOne
@ABri,你不可能认真建议所有正则表达式都应该在main()函数中初始化,然后通过所有函数传递到需要它们的地方。 :o - Jay
显示剩余2条评论

2
短声明语法
reg, _ := regexp.Compile(`[^a-z\s]`)

全局作用域不允许使用。请明确使用var代替。
var reg, _ = regex.Compile(`[^a-z\s]`)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接