英文:
Runtime Const in Golang
问题
在一些语言中,比如Java和C++,可以创建常量,并在构造函数中为其赋值(之后不可更改)。在Golang中是否有办法做到这一点,以便可以创建一个在运行时才知道值的常量?谢谢!
英文:
In some languages, such as Java and C++, constants can be created and then assigned their value during the constructor (and then not changed after that). Is there any way to do this in Golang so that a constant whose value won't be known until runtime can be created? Thanks in advance!
答案1
得分: 15
在Go语言中,常量是在编译时设置的。可以在文档的相关部分查看详细信息:https://golang.org/doc/effective_go.html#constants
在Go语言中,常量就是常量。它们在编译时创建,即使在函数中定义为局部变量,也只能是数字、字符(符文)、字符串或布尔值。由于编译时的限制,定义常量的表达式必须是常量表达式,可以由编译器计算。例如,1<<3是一个常量表达式,而math.Sin(math.Pi/4)不是,因为对math.Sin的函数调用需要在运行时发生。
英文:
Constants in go are set at compile time, see the relevant section in the docs here: https://golang.org/doc/effective_go.html#constants
> Constants in Go are just that—constant. They are created at compile time, even when defined as locals in functions, and can only be numbers, characters (runes), strings or booleans. Because of the compile-time restriction, the expressions that define them must be constant expressions, evaluatable by the compiler. For instance, 1<<3 is a constant expression, while math.Sin(math.Pi/4) is not because the function call to math.Sin needs to happen at run time.
答案2
得分: 4
根据Go语言规范和Go运行时,目前没有支持运行时常量的构造。但是你可以通过使用未导出的字段和"getter"方法来模拟运行时常量,例如:
package wrapper
type Immutable struct {
value int
}
func (i Immutable) Get() int { // 你可以选择指针或值接收器
return i.value
}
func New(value int) Immutable {
return Immutable{value}
}
你可以使用New()
构造函数一样的函数创建Immutable
类型的值,并且在wrapper
包之外的任何地方都无法修改封装的int
值(Immutable.value
)。
(注意:这里的"no one"指的是除了使用unsafe
包的人之外的任何人,但这并不算。即使在Java中,你也可以使用Java反射来更改final
属性的值。)
英文:
As stated, there are no constructs supporting runtime constants in Go backed by the language spec or the Go runtime.
You can simpulate runtime constants though with unexported fields and with a "getter" method, e.g.:
package wrapper
type Immutable struct {
value int
}
func (i Immutable) Get() int { // You may choose between pointer or value receiver
return i.value
}
func New(value int) Immutable {
return Immutable{value}
}
You can create values of Immutable
with the New()
constructor-like function, and no one* outside of package wrapper
will be able to modify the wrapped int
value (Immutable.value
).
(*Note: no one means no one who is not touching package unsafe
, but that doesn't count. Even in Java you can change values of final
attributes using Java reflection.)
答案3
得分: 3
不,这是不可能的。常量只能保存在编译时已知的字符串和数字。
英文:
No, it is not possible. constants can only hold strings and numbers known at compile time.
答案4
得分: 0
一种方法是使用未导出的结构体,并定义使用该未导出类型的函数。
// ./vendor/structstuff/structstuff.go
package structstuff
type constVal struct {
val int
}
func (c *constVal) Value() int {
return c.val
}
var ExportedVal constVal
func init() {
ExportedVal.val = 43
}
func CallFunc(c constVal) int {
return c.val
}
// ./main.go
package main
import (
"fmt"
"structstuff"
)
func main() {
fmt.Println(structstuff.ExportedVal.Value())
fmt.Println(structstuff.CallFunc(structstuff.ExportedVal))
}
英文:
One way to do it is using an unexported struct and define functions that use that unexported type specifically.
// ./vendor/structstuff/structstuff.go
package structstuff
type constVal struct {
val int
}
func (c *constVal) Value() int {
return c.val
}
var ExportedVal constVal
func init() {
ExportedVal.val = 43
}
func CallFunc(c constVal) int {
return c.val
}
// ./main.go
package main
import (
"fmt"
"structstuff"
)
func main() {
fmt.Println(structstuff.ExportedVal.Value())
fmt.Println(structstuff.CallFunc(structstuff.ExportedVal))
}
答案5
得分: 0
你可以在运行时使用匿名函数来充当常量,如下所示:
package main
import (
"fmt"
)
func main() {
// 定义一个运行时常量
pi := func() float64 { return 3.141592653589793238 }
// 使用常量
x := pi() * 123
// 打印结果
fmt.Println("X = ", x)
}
你可以在这个链接中查看代码示例:https://play.golang.org/p/Q0dGfwL_Y4P
英文:
You can use an anonymous function at Runtime to act just like constants as follows:
package main
import (
"fmt"
)
func main() {
// Define a Runtime constant
pi := func() float64 { return 3.141592653589793238 }
// Use the constant
x := pi() * 123
// Print the result
fmt.Println("X = ", x)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论