Runtime Const in Golang

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

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 (
	&quot;fmt&quot;
	&quot;structstuff&quot;
)

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 (
	&quot;fmt&quot;
)

func main() {
	
	// Define a Runtime constant
	
	pi := func() float64 { return 3.141592653589793238 }
	
	// Use the constant
	
	x := pi() * 123
	
	// Print the result
	
	fmt.Println(&quot;X = &quot;, x)
}

https://play.golang.org/p/Q0dGfwL_Y4P

huangapple
  • 本文由 发表于 2016年1月27日 08:43:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/35026810.html
匿名

发表评论

匿名网友

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

确定