Ryan
Ryan

Reputation: 1221

Runtime Const in 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!

Upvotes: 17

Views: 12298

Answers (5)

Abdelaziz Elrashed
Abdelaziz Elrashed

Reputation: 743

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)
}

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

Upvotes: 0

icza
icza

Reputation: 417412

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.)

Upvotes: 4

OneOfOne
OneOfOne

Reputation: 99195

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))
}

Upvotes: 0

Chris Cherry
Chris Cherry

Reputation: 28554

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.

Upvotes: 16

Joonazan
Joonazan

Reputation: 1416

No, it is not possible. constants can only hold strings and numbers known at compile time.

Upvotes: 3

Related Questions