如何从变量声明一个常量?

huangapple go评论86阅读模式
英文:

How to declare a constant from a variable?

问题

问题是什么:

我想从一个变量声明一个常量。以下是我想要做的非常简单的版本:

someVar := 1
const someConst = someVar // 错误:常量初始化器someVar不是一个常量
fmt.Printf("%d %d", someVar, someConst)

我如何将someConst声明为常量?在Go语言中是否不可能实现这一点?

我为什么想要这样做:

someVar是一个全局变量。它可以改变是可以接受的。someConst是函数作用域的。在该函数的作用域内,它不应该改变。

以数据库术语来说:someConstsomeVar的一个不可变快照。

英文:

What is the problem:

I would like to declare a constant from a variable. Here is a very simple version of what I'd like to do:

Go playground

someVar := 1
const someConst = someVar // error: const initializer someVar is not a constant
fmt.Printf("%d %d", someVar, someConst)

How can I make someConst a constant? Is this impossible in go?

Why do I want this?

someVar is a global Variable. It is fine that this can change. someConst is function scoped. For the scope of this function it should not change.

In DB terms: someConst is an immutable snapshot of someVar

答案1

得分: 6

你不能这样做。Go语言的常量必须是编译时常量。

常量声明将一组标识符(常量的名称)绑定到一组常量表达式的值。

常量表达式只能包含常量操作数,并在编译时进行求值。

你示例中的someVar是一个变量,它不符合"常量操作数"的要求。

如果包级别的变量在函数执行过程中可能会发生变化,而你不想观察到这种变化,可以创建该变量的本地副本,并使用本地副本。

还要注意,如果变量的值可能因为(并发的)goroutine而发生变化,在制作副本时必须进行同步访问(就像在其他goroutine中对其进行写入一样)。

例如:

var (
    someVarMu sync.RWMutex
    someVar   = 1
)

func foo() {
    someVarMu.RLock()
    myVar := someVar
    someVarMu.RUnlock()

    // 使用myVar
    fmt.Println(myVar)
}
英文:

You can't. Go's constants must be compile-time constants.

> A constant declaration binds a list of identifiers (the names of the constants) to the values of a list of constant expressions.

And

> Constant expressions may contain only constant operands and are evaluated at compile time.

someVar in your example is a variable, it does not qualify for the "constant operands".

If the package level variable may change during the execution of your function which change you don't want to observe, make a local copy of the variable, and use the local copy.

Also note that if the variable's value may change due to a (concurrent) goroutine, access to it (when making the copy) must be synchronized (just like the write to it in other goroutines).

For example:

var (
	someVarMu sync.RWMutex
	someVar   = 1
)

func foo() {
	someVarMu.RLock()
	myVar := someVar
	someVarMu.RUnlock()

	// Use myVar
	fmt.Println(myVar)
}

huangapple
  • 本文由 发表于 2022年1月5日 22:14:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/70594365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定