Friday, April 16, 2021

Golang - Constants

Constants are defined during the compilation process.

Constants may or may not have a type.

All basic literals are unnamed constant values.
 

1
  3.14
   "hello"
  true
   false


During runtime, named constants will be replaced with their values.


Declarations



Some programs may have a "Magic Number".

"Magic number" refers to a value that has no name and cannot be identified without tracing codes.

It's just a simple example with the "magic number" below.

exp/main.go

package main

import (
    "fmt"
    "math"
)

func main() {
    var radius = 5

    // People may wonder what the number 3.14159 means.
    var circleArea = math.Pow(float64(radius), 2) * 3.14159

    fmt.Printf("Area of a circle with radius(%d): %f\n", radius, circleArea)
}


Result:

  Area of a circle with radius(5): 78.539750


With best practice, we should get rid of "magic number" if possible to improve readability.

We can introduce constants and adjust the example as following.

exp/main.go

package main

import (
    "fmt"
    "math"
)

func main() {
    // Declare a constant
    const pi float64= 3.14159

    var radius = 5
    // Use Constants to improve readability
    var circleArea = math.Pow(float64(radius), 2) * pi
    fmt.Printf("Area of a circle with radius(%d): %f\n", radius, circleArea)
}


It can also help to improve code safety.
Consider the following example.

exp/main.go

package main

import (
    "fmt"
)

func main() {
n, m := 1, 0
fmt.Println(n / m)
}


When we build it, no errors are thrown, but when we run it, we get 'panic: runtime error: integer divide by zero'.

If we change it to look like this with Constants, we can catch the 'invalid operation: division by zero' mistake during the compile process.

exp/main.go

package main

import (
    "fmt"
)

func main() {
const n int = 1
const m int = 0
fmt.Println(n / m)
}



Rule of constants



We don't need to make constants all upper case in Go (as is the case in other languages).

However, if you wish to expose it to other packages, you must make the initial character upper case.

1. Constants need initial value.


const max int


Error:

  missing value in const declaration



2. Constants are immutable.



  const max int = 100
  max = 101


Error:

  cannot assign to max



3. We cannot initialize a constant to a run-time value.

Functions

// A function call belongs to runtime.
  const max int = getMaxValue()


Error:

  const initializer getMaxValue() is not a constant


Variables

  var min = 5
// Variables belong to runtime
  const max int = min * 10


Error:

  const initializer min * 10 is not a constant



4. There is an exception to use len() function with constant value.


  const max int = len("Hello World")
  fmt.Println("max:", max)


Result:

  max: 11



5. We can use non-numeric type for declaring constants.


6. We can use constant expression.


  const min = 10
  const max int = min * 10

  fmt.Println("max:", max)


Result:

  max: 100



Type-less Constants



Constants do not require types until they are required.

When you declare a constant without specifying a type, it becomes an untyped constant (also known as a typeless constant).


  const pi = 3.14


More Details:

    3.14159 is typeless float literal.
    Also, constant pi is typeless as well.

What are the benefits of utilizing typeless constants?

Consider the following example, in which we must give the type conversion using a type constant. 


  const pi float64 = 3.14
  const calculatedPi int int(pi * 100)

  result := 2 * calculatedPi

  fmt.Println("result:", result)


Result:

  result: 628


We can change it using typeless constants as shown below.


  const pi = 3.14
  const calculatedPi = pi * 100

  result := 2 * calculatedPi

  fmt.Println("result:", result)

 
Result:

  result: 628


Then we don't need to convert the type for constant calculatedApi.
And Go will assist with determining the type when assigning type and value to variable results.

More info:    
     pi => typeless
    calculatedApi => typeless
    result => it is a variable and it need type => float64

Default Type



You might be wondering how Go figure out the type for us using the preceding example.

There are default type for each value:

    i := 1                    => int

    f := 3.14               => float64

    b := true              => bool

    s := "Hello"           => string

    r := 'A'                  => rune


Go evaluates the expression and then sets the typeless value to its default value.


  myValue := 1 + 3.14
  fmt.Println("myValue:", myValue)


Result:

  myValue: 4.14


What Go do for us is:

1. Calculate the value of expression first (1 + 3.14 = 4.14)
2. Determine that 4.14 is typeless float literal
3. Since we need a type for declaring a variable and the value is typeless float literal, Go use default type float64 to return


IOTA



It's possible that we'll need to declare many consts with increment numbers.

    
const (
    Monday = 1
    Tuesday = 2
    Wednesday = 3
  )


We can use IOTA to simplify the code like below. 

IOTA starts with 0.


  const (
    Monday = iota + 1
    Tuesday
    Wednesday
  )

  fmt.Printf("%v\n%v\n%v\n", Monday, Tuesday, Wednesday)


Result:

  1
  2
  3


If the type and value of constants are not specified, they are taken from the previous declaration.

Furthermore, iota will generate a unique number.

As a result, we may use this format to specify the corresponding constants.

Furthermore, 'blank identifier' can assist in avoiding the assignment.


  const (
    Monday = iota + 1
    Tuesday
    Wednesday
    _
    Friday
  )

  fmt.Printf("%v\n%v\n%v\n%v\n", Monday, Tuesday, Wednesday, Friday)


Result:

  1
  2
  3
  5


No comments:

Post a Comment