Go Series: Variable Declaration Best Practices & Gotchas
Tags: go, beginners
Published: 2022-09-26 10:14:27


![Golang Logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tdkgcszo71tdh7eans9.png)

{% replit @achristoph/Variables  %}


## Declaring variables

To declare a variable in go, you can either:

- Declare without initial value, the type has to be declared:

 ```var name string```

- Declare with initial value, the type is optional as it is implicitly inferred by go:

With type declaration: ```var name string = "go"```

Without type declaration: ```var name = "go"```

- Short declaration: ```string := "go"```
One important note on using this short declaration: be aware of variable shadowing, it may look you are reusing the variable, but it is not the case, unchecked colon can make all the difference
```go
count := 1
if count > 0 {
// this is a new count variable within the block
// so vigilant when using same variable name
  count := 2
  fmt.Println(count) // print 2
}
fmt.Println(count) // print 1
```
- Mixed of value assignment to existing variable and short declarations, this is one of the most common things you write: assigning a value and possible error from a function to variables. I'll discuss more on the best practices in function to avoid the common errors
```go
var result int
result, err:= calculate()
fmt.Println(result, err)
```

- Multiple variable declaration can be done in one-liner for same type, allowing omitting type for the other variables :
```var a,b int```
or multiline for same or different type:
```go
  var (
    c string
    d bool
  )
```

## Two kinds of variables based on the scope:

1.Package level variable - **warning**: only used this as **constant** . For a good reason, mutating the value will be hard to track.
```go
package main
var myPkgVar = 1
func printMyVar(){
  fmt.Println(myPkgVar)
}
```
Constants value are determined at compile time - only primitive values or static computation, otherwise Go will throw compile error if you try. So boolean, numeric, string, rune work.

These work:
```go
const myArrLen = len([1]int{1})
const myStrLen = len("str")
const myNum = 2/4
```
but no these dynamic values:
```go
const t = time.Now()
const slice = []int{}
```

2.Function level variable - this is what we usually use, always strive to use function-level variable. We'll look more why when we explore function in go , as **everything** in **passed by value**

3.There's actually the third one - the 'universe level' block which we'll never abuse but good to know. The following will surprisingly compile without error as true is one of a set of predeclared identifiers on the very top scope that can be overshadowed
```go
true :=1
fmt.Println(true)
```

## Few more notes
- Unused variables will throw error, this is go mechanism to reduce code clutter, however package-level variable is not checked, another reason to avoid using it. Also const variable is not checked either, this is because it is calculated at compile time - no side effect, so if not used, it's not included in the compiled code, still we do want to avoid unused variable cluttering, this is why const is also less used than var, the combination of var & pass-by-value is enough as a const replacement in general.
- Idiomatic go uses camelCase for variable naming
- Capitalized name has special meaning - it indicates it is accessible outside of package it is defined in
- Go prefer short variable names. These short names serve two purposes. The first is that they eliminate repetitive typing, keeping your code shorter. Second, they serve as a check on how complicated your code is. If you find it hard to keep track of your short-named variables, it’s likely that your block of code is doing too much.
- Package-level names on the other hand should be more descriptive since it's more widely used by definition.

Next post will be a big topic: function , so much to cover that it might need several parts that focus on different aspect of it.