Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constants in Go established during init

Tags:

go

In my Go program, there are configuration values that I want to be constant for the duration of program execution, but that I want to be able to change at the deployment site. As far as I can tell, there's no way to achieve this with the const keyword, since (again, as far as I can tell) its value must be a constant specified at compile time. This means that the only way to achieve what I want would be to declare normal variables and initialize them during the package's init function. It's not that that won't work, but rather that there will now be nothing to prevent these pseudo-constant's values from changing.

My two questions are:

  1. Am I missing something about how const works?
  2. Assuming I'm not, what's the preferred way to handle this? A public function that returns a private variable that I never expose, never changing it? Just hoping people don't alter the variables, since they're really configuration settings?
like image 728
Benjamin Pollack Avatar asked Feb 15 '13 18:02

Benjamin Pollack


People also ask

How are constants declared in Go?

There can be any basic data type of constants like an integer constant, a floating constant, a character constant, or a string literal. How to declare: Constants are declared like variables but in using a const keyword as a prefix to declare a constant with a specific type. It cannot be declared using “=” syntax.

Does Golang have const?

In Golang, all constants are untyped unless they are explicitly given a type at declaration. Untyped constants allow for flexibility. They can be assigned to any variable of compatible type or mixed into​ mathematical operations.

How do untyped constants interact with Go's typing system?

Untyped Constants They are not given a fixed type yet, like int32 or float64 or string , that would force them to obey Go's strict type rules. Note that, Although the value 1 is untyped, it is an untyped integer. So it can only be used where an integer is allowed.

What is untyped constant?

An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required. For example default type for integer constant is int or it's float64 for floating-point number. In program V variable c is being set to untyped constant expression 1 .


3 Answers

Create a file "config.go" and create the vars you want to expose.

Don't export them (make them all lower case). Instead create public (upper case) funcs that give access to each item.

package config

var x = 10

func X() int {
   return x
}

When you want those variables you simply import ./config and use them in code as follows:

if config.X()

Obviously, you can set the variables in the package init.

like image 182
Chris Pfohl Avatar answered Oct 19 '22 04:10

Chris Pfohl


The following code is almost the same as the second method of @Christopher, except that it is not a module, it located in the main package.

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
}

you can use config to load and save the config file.

like image 1
Joe Avatar answered Oct 19 '22 05:10

Joe


This is a very good question because it delves into what I suspect may be an omission from Go - immutable state.

From the language reference, "constant expressions may contain only constant operands and are evaluated at compile-time."

You cannot make vars constant, which is a shame. Joe's answer proposes encapsulation as a solution, which will work well - but it's verbose, tedious and might introduce errors.

By comparison, many impure functional languages combine mutable variables with single-assignment immutable values. For example, Scala has the keywords 'val' and 'var'; the meaning of Scala's 'var' is quite similar to Go's 'var'. Immutability is a useful tool in the toolbox because referentially-transparent side-effect-free functions can be written, alongside stateful mutable procedural code. Both have their place. Immutability is also an valuable tool for concurrency because there is no worry about possible race conditions if immutable values are shared between goroutines.

So in my opinion, amongst its many strengths, this is one of Go's shortcomings. It would presumably not be hard to support vals as well as vars, the difference being that the compiler checks that each val is assigned exactly once.

Until that feature is added, you have encapsulation as your only option.

like image 1
Rick-777 Avatar answered Oct 19 '22 05:10

Rick-777