在我的Go程序中,有一些配置值我希望在程序执行期间保持不变,但我希望能够在部署站点进行更改。据我所知,使用const
关键字无法实现此目的,因为(据我所知),其值必须是编译时指定的常量 。这意味着实现我想要的唯一方法是声明正常变量并在包的init
函数中初始化它们。并不是那不会起作用,而是现在没有什么可以防止这些伪常数的值发生变化。
我的两个问题是:
const
的工作原理?答案 0 :(得分:3)
创建一个文件“config.go”并创建要公开的变种。
不要导出它们(使它们全部小写)。而是创建允许访问每个项目的公共(大写)func
。
package config
var x = 10
func X() int {
return x
}
如果您想要这些变量,只需import ./config
并在代码中使用它们,如下所示:
if config.X()
显然,您可以在包init
中设置变量。
答案 1 :(得分:1)
以下代码与@Christopher的第二种方法几乎相同,只是它不是一个模块,它位于主包中。
package main
import (
"os"
)
type Config struct {
debug bool
key string
proxyNumber int
}
func (c *Config) Debug() bool {
return c.debug
}
func (c *Config) Key() string {
return c.key
}
func (c *Config) ProxyNumber() int {
return c.proxyNumber
}
const (
CONFIG_NAME = "config.ini"
)
var config *Config
func init() {
DefaultConfig()
if Exists(CONFIG_NAME) {
//try to save the config file
}else {
//try to load from the config file
}
}
func DefaultConfig() {
config = &Config{debug:true, key:"abcde",
proxyNumber:5,
}
}
//Exist: check the file exist
func Exists(path string) bool {
_, err := os.Stat(path)
if err == nil { return true }
if os.IsNotExist(err) { return false }
return false
}
您可以使用config加载和保存配置文件。
答案 2 :(得分:1)
这是一个非常好的问题,因为它深入研究了我怀疑可能是Go-immutable状态的遗漏。
从language reference开始,“常量表达式可能只包含常量操作数,并在编译时进行求值。”
你不能让变量不变,这是一种耻辱。 Joe的回答提出封装作为一种解决方案,它可以很好地工作 - 但它冗长,乏味并且可能会引入错误。
相比之下,许多不纯的函数语言将可变变量与单赋值不可变值组合在一起。例如,Scala有关键字'val'和'var'; Scala的'var'的含义与Go的'var'非常相似。不变性是工具箱中的一个有用工具,因为可以编写引用透明的无副作用函数,以及有状态可变过程代码。两者都有自己的位置。不可变性也是一种有价值的并发工具,因为如果在goroutine之间共享不可变值,就不用担心可能的竞争条件。
所以在我看来,在众多优势中,这是Go的缺点之一。它可能并不难以支持val和vars,不同之处在于编译器会检查每个val只分配一次。
在添加该功能之前,您已将封装作为唯一选项。
答案 3 :(得分:0)
您可以这样做:
package main
import (
"fmt"
"strconv"
)
var a string
func main() {
myvar, err := strconv.Atoi(a)
if err != nil {
fmt.Println(err)
}
fmt.Println(myvar)
}
并使用
编译程序go build -ldflags '-X main.a 10' test.go
这样你就可以在编译期间定义一个常量。
答案 4 :(得分:0)