Learning GO with Codeacademy
Tags: go, codeacademy, beginners
Published: 2020-11-28 18:22:23

# Introduction <a name="introduction"></a>
Go was developed at Google with the goal to [eliminate the slowness and clumsiness of software development at Google, and thereby to make the process more productive and scalable](https://talks.golang.org/2012/splash.artcicle). In other words, Go is supposed to make development faster and easier for developers.

It has modern features like garbage collection and also takes advantage of multi-core computer capabilities with built-in concurrency support. 

Read up on [why Go has become popular](https://dev.to/pavanbelagatti/why-is-go-so-damn-popular-among-developers-2d6h).

* [Go Cheatsheet](https://www.codecademy.com/learn/learn-go/modules/learn-go-introduction/cheatsheet)
* [Setting up Go locally](https://www.codecademy.com/articles/setting-up-go-locally)
* [List of Go's standard packages](https://golang.org/pkg/)
* [Golang.org](https://golang.org/)

Other learning resources:
* [A Tour of Go](https://tour.golang.org/welcome/1)
* [Effective Go](https://golang.org/doc/effective_go.html)
* [The Go Programming Language Specification](https://golang.org/ref/spec)
* [The Go Programming Language](https://www.gopl.io/) (book)


### Compiling & Running Files <a name="introduction-1"></a>
A compiler translates Go code into an _executable_/_binary_ file. 

Compile and run a file called `file_name.go`:
```bash
go build file_name.go
./file_name
```

Alternatively, using `go run` does combine both compilation and execution of code, but does not create an executable file:
```bash
go run file_name.go
```

### Basic Go Structure: Packages <a name="introduction-2"></a>
Let's look at the following code:
```go
package main

import "fmt"

func main() {
  fmt.Println("Hello World")
}
```

* `package main`
  * This is a package declaration.
  * Every Go program starts with one.
  * It informs the compiler whether to create an executable or _library_.
    * A library doesn't execute code. It is a collection of code that can be used in other programs.
  * `package main` creates an executable file.
* `import "fmt"`
  * `import` imports code from other packages
  * Packages are enclosed with double quotes `"`
* `func main() {...}` 
  * While we define the `main` function, we never explicitly tell `main` to run its block of code.
  * The `main` function is special: a file that has a `package main` declaration will automatically run the `main` function

### Importing Multiple Packages <a name="introduction-3"></a>
To import multiple packages, we can write
```go
import "package1"
import "package2"
```
or
```go
import (
  "package1"
  "package2"
)
```

Providing an _alias_ to a package:
```go
import (
  p1 "package1"
  "package2"
)
```

By using an alias, we can call functions from `package1` by using `p1` like this:
```go
p1.SampleFunc()
```
instead of:
```go
package1.SampleFunc()
```

### Comments <a name="introduction-4"></a>
Go encourages the use of comments for describing what functions do. It gets used by [Go's documentation tool](https://github.com/golang/go/wiki/Comments).
```go
// This is a comment
/*
This is a multiline
comment.
*/
```
### Go Resources <a name="introduction-5"></a>
Go has a built-in documentation system. Use the command `go doc` followed by a package name, e.g.:
```bash
go doc fmt
```
Get more specific information about a function in a package, e.g:
```bash
go doc fmt.Println
```
Note: The capitalization of the function doesn't matter, this will also work: `go doc fmt.println`.

### Fun Application <a name="introduction-6"></a>
```go
package main

import "fmt"

func main() {
  const gopher = 
"      `.-::::::-.`\n" +
"  .:-::::::::::::::-:.\n" +
"  `_:::    ::    :::_`\n" +
"   .:( ^   :: ^   ):.\n" +
"   `:::   (..)   :::.\n" +
"   `:::::::UU:::::::`\n" +
"   .::::::::::::::::.\n" +
"   O::::::::::::::::O\n" +
"   -::::::::::::::::-\n" +
"   `::::::::::::::::`\n" +
"    .::::::::::::::.\n" +
"      oO:::::::Oo\n"

  const dog = 
"  __      _\n" +
"o'')}____//\n" +
" `_/      )\n" +
" (_(_/-(_/\n"
  fmt.Println(gopher)
  fmt.Println(dog)
}
```

# Variables and Formatting <a name="variables"></a>
Example program showing 
* string
* number (`int8`)
* boolean

```go
package main

import "fmt"

func main() {
  var stationName string
  var nextTrainTime int8
  var isUptownTrain bool
  
  stationName = "Union Square"
  nextTrainTime = 12
  isUptownTrain = false
  
  fmt.Println("Current station:", stationName)
  fmt.Println("Next train:", nextTrainTime, "minutes")
  fmt.Println("Is uptown:", isUptownTrain)
}
```

### Literals   <a name="variables-1"></a>
Literals are values written into code "as they are", e.g. `109`, or `"hello world"`. They are _unnamed_ values.

### Constants and Variables
* Constants cannot be updated while the program is running. 
* Variables can update their value

```go
package main

import "fmt"

func main() {
  const earthsGravity = 9.80665
  
  fmt.Println(earthsGravity)
}
```
### Basic Data Types in Go
* int
* float
* complex

### Basic Numeric Types in Go
![Screen Shot 2020-11-22 at 6.11.07 PM](https://dev-to-uploads.s3.amazonaws.com/i/0kmcb3h9g63i88ezjfnz.png)

[Numeric types documentation](https://golang.org/ref/spec#Numeric_types) 
### What is a Variable?
Variables are defined with the `var` keyword and two pieces of information: the name that we will use to refer to them and the type of data stored in the variable.

```go
var lengthOfSong uint16
var isMusicOver bool
var songRating float32
```

You can declare and assign a variable in one line, with or without declaring the type specifically:
```go
var firstName = "Kat"
var middleName string = "Xenia"
fmt.Println(firstName + ", " + middleName)
```
### Zero Values
Even before we assign anything to our variables they hold a value. Go's designers attempted to make these "sensible defaults" that we can anticipate based on the variable's types.

```go
var classTime uint32
var averageGrade float32
var teacherName string
var isPassFail bool
 
fmt.Println(classTime) // Prints 0
fmt.Println(averageGrade) // Prints 0
fmt.Println(teacherName) // Doesn't print anything, default: ""
fmt.Println(isPassFail) // Prints false
```
### Inferring Type
There is a way to declare a variable without explicitly stating its type using the short declaration `:=` operator. We might use the `:=` operator if we know what value we want our variable to store when creating it.

The following defines a `bool`, `float`, `int`, and `string` without specifying the type:
```go
nuclearMeltdownOccurring := true
radiumInGroundWater := 4.521
daysSinceLastWorkplaceCatastrophe := 0
externalMessage := "Everything is normal. Keep calm and carry on."
```
Floats created this way are of type `float64`. Integers created this way are either `int32` or `int64`.

An alternative syntax to declare a variable and infer its type is:
```go
var nuclearMeltdownOccurring = true
var radiumInGroundWater = 4.521
var daysSinceLastWorkplaceCatastrophe = 0
var externalMessage = "Everything is normal. Keep calm and carry on."
```

### Default int Type
There is one more common way to define an `int` in Go. Computers actually have a default length for the data in the Read-Only Memory (ROM). Some newer computers may have more processing power and can store/handle bigger chunks of data. These computers might be using a 64-bit architecture, but other computers still run on 320bit architecture and work just fine.

By providing the type `int` or `uint`, Go will check to see if the computer architecture is running on is 32-bit or 64-bit. Then it will either provide a 32-bit `int` (or `uint`) or a 64-bit one depending on the computer itself. 

It is recommended to use `int` unless there's a reason to specify the size of the int (like knowing that value will be larger than the default type, or needing to optimize the amount of space used).

The following two variables are integers of either 32 or 64 bits:
```go
var timesWeWereFooled int
var foolishGamesPlayed uint
```

When a variable is declared and assigned a value using the `:=` operator, it will be the same type as if it were declared as an `int`:
```go
consolationPrizes := 2
```

### Multiple Variable Declaration
There are more than one way to declare multiple variables on a single line. 
```go
var part1, part2 string
part1 = "To be..."
part2 = "Not to be..."
```

```go
quote, fact := "Bears, Beets, Battlestar Galactica", true
fmt.Println(quote) // Prints: Bears, Beets, Battlestar Galactica
fmt.Println(fact) // Prints: true
```

# The fmt Package
`fmt` is one of Go's core packages. It helps _format_ data, which is why it's sometimes referred to as the format package.

There are a few methods in the [`fmt` package](https://golang.org/pkg/fmt/):
* Printing data to the terminal
  * `Println()`
  * `Print()`
  * `Printf()`
* Formatting (without printing to the terminal)
  * Sprint()
  * Sprintln()
  * Sprintf()
* Getting user input
  * Scan()

### The Print Method
`fmt.Println()` allows us to print to the terminal. It has some default styling built-in that makes viewing data easier. `fmt.Println()` prints its _arguments_ with an included space in between each argument and adds a line break at the end.

Example:
```go
fmt.Println("Println", "formats", "really well")
fmt.Println("Right?")
```

```bash
Println formats really well
Right?
```

In the case that default formatting is not wanted, `fmt.Print()` is more appropriate. It does not add default spacing, nor a line break.
### The Printf Method
Using `fmt.Println()` and `fmt.Print()`, we have the ability to concatenate strings, i.e. combine different strings into a single string:

```go
guess := "C"
fmt.Println("Is", guess, "your final answer?")
// Prints: Is C your final answer?
```

With `fmt.Printf()`, we can _interpolate_ strings, or leave placeholders in a string and use values to fill in the placeholders.

```go
selection1 := "soup"
selection2 := "salad"
fmt.Printf("Do I want %v or %v?", selection1, selection2)
// Prints: Do I want soup or salad?
```

The `%v` in the string is the placeholder and known as a _verb_ in Go.

### Different Verbs
In addition to `%v`, Go has a variety of [useful verbs](https://golang.org/pkg/fmt/#hdr-Printing).

Example: `%T` prints out the type of a variable
```go
specialNum := 42
fmt.Printf("This value's type is %T.", specialNum)
// Prints: This value's type is int.
 
quote := "To do or not to do"
fmt.Printf("This value's type is %T.", quote)
// Prints: This value's type is string.
```

Example: `%d` interpolates a number into a strgin
```go
votingAge := 18
fmt.Printf("You must be %d years old to vote.", votingAge)
// Prints: You must be 18 years old to vote. 
```

Example: `%f` interpolates a float into a string, with the option to limit the precision:
```go
gpa := 3.8
fmt.Printf("You're averaging: %f.", gpa)
// Prints: You're averaging 3.800000.

fmt.Printf("You're averaging: %.2f.", gpa)
// Prints: You're averaging 3.80.
```

### Sprint and Sprintln
`fmt.Sprint()` and `fmt.Sprintln()` format strings instead of printing them out. 

The following example shows how `fmt.Sprint()` returns a value that can be stored in a variable and used later.
```go
grade := "100"
compliment := "Great job!"
teacherSays := fmt.Sprint("You scored a ", grade, " on the test! ", compliment)
 
fmt.Print(teacherSays)
// Prints: You scored a 100 on the test! Great job!
```

`fmt.Sprint()` doesn't include spaces or newline:
```go
quote = fmt.Sprintln("Look ma,", "no spaces!")
fmt.Print(quote) // Prints Look ma, no spaces!
```


### The Sprintf Method
`fmt.Sprintf()` uses verbs just like `fmt.Printf()`:
```go
  template := "I wish I had a %v."
  pet := "puppy"
  
  var wish string
  
  // Add your code below:
  wish = fmt.Sprintf(template, pet)
  
  fmt.Println(wish)
```
### Scan(): Getting User Input
```go
fmt.Println("How are you doing?") 
 
var response string 
fmt.Scan(&response)
 
fmt.Printf("I'm %v.", response) 
```
`fmt.Scan()` 
* reads in a string up until a whitespace
* expects _addresses_ for arguments

# Conditionals

The `if` statement does not necessarily need parentheses:
```go
alarmRinging := true
if alarmRinging {
  fmt.Println("Turn off the alarm!!") 
}
```

```go
isHungry := false
if (isHungry) {
  fmt.Println("Eat the cookie") 
} else {
  fmt.Println("Step away from the cookie...")
}
```

### Comparison & Logical Operators
To use a comparison operator, we have two values (or _operands_) with a comparison operator in between the two values.

```go
if day == "Saturday" || day == "Sunday" {
  fmt.Println("Enjoy the weekend!")
} else {
  fmt.Println("Do some work.")
}
```

### else if Statement

```go
position := 2
 
if position == 1 {
  fmt.Println("You won the gold!")
} else if position == 2 {
  fmt.Println("You got the silver medal.")
} else if position == 3 {
  fmt.Println("Great job on bronze.")
} else {
  fmt.Println("Sorry, better luck next time?")
}
```

### switch Statement
```go
clothingChoice := "sweater"
 
switch clothingChoice {
case "shirt":
  fmt.Println("We have shirts in S and M only.")
case "polos":
  fmt.Println("We have polos in M, L, and XL.")
case "sweater":
  fmt.Println("We have sweaters in S, M, L, and XL.")
case "jackets":
  fmt.Println("We have jackets in all sizes.")
default:
  fmt.Println("Sorry, we don't carry that")
}
// Prints: We have sweaters in S, M, L, and XL.
```

### Scoped Short Declaration Statement
We can provide a short variable declaration before we provide a condition in either `if` or `switch` statements.

```go
x := 8
y := 9
if product := x * y; product > 60 {
  fmt.Println(product, "  is greater than 60")
}
```

Notice that the variable declaration is separated from the condition using a semi-colon `;`.

```go
switch season := "summer" ; season {
case "summer"
  fmt.Println("Go out and enjoy the sun!")
}
```

The variable that is declared using the short variable declaration is _scoped_ to the statement blocks. This means that the variable is only accessible within the blocks of those statements and not anywhere else.

This code will throw an error:
```go
x := 8
y := 9
if product := x * y; product > 60 {
  fmt.Println(product, "  is greater than 60")
}
fmt.Println(product)
```

### Randomizing
Go has a `math/rand` library that has methods to generate random numbers.

```go
import (
  "math/rand"
  "fmt"
)
 
func main() {
  fmt.Println(rand.Intn(100))
}
```
The `rand.Intn()` method takes an argument, which is the maximum value that the method will return.  It will return a random integer from `0` to `100`.

### Seeding
Go _seeds_ (chooses) a number as a starting point for generating random numbers. By default, the seed value is `1`. We can provide a new seed value using the method `rand.Seed()` and passing in an integer.

The seed number should always be a unique number, which can be achieved using time.

```go
package main
 
import (
  "fmt"
  "math/rand"
  "time"
)
 
func main() {
  rand.Seed(time.Now().UnixNano())
  fmt.Println(rand.Intn(100))
}
```
`time.Now().UnixNano()` results in the difference in time (in nanoseconds) since January 1st, 1970 UTC. Check out the [UnixNano documentation](https://golang.org/pkg/time/#Time.UnixNano) for more details.

# Functions

```go
func doubleNum(num int) int {
  return num * 2
}
```

The _call site_ is the place where a function is called. Values that are returned from functions are set from within the function to the call site. A function can be given a return _type_. 

```go
func getLengthOfCentralPark() int32 {
  var lengthInBlocks int32
  lengthInBlocks = 51
  return lengthInBlocks
}
```

Function parameters are variables that are used within the function. When calling a function, we give _arguments_, which are the values that we want those parameter variables to take. 

```go
func multiplier(x int32, y int32) int32 {
  return x * y
}
```

Since both parameters in the function above are the same, we could write it as:
```go
func multiplier(x, y int32) int32 {
  return x * y
}
```

### Scope
Scope keeps the _namespace_, the available variables and keywords, cleaner. Variables or functions can only be referred to in their respective namespace.


### Multiple Return Values
```go
func GPA(midtermGrade float32, finalGrade float32) (string, float32) {
  averageGrade := (midtermGrade + finalGrade) / 2
  var gradeLetter string
  if averageGrade > 90 {
    gradeLetter = "A"
  } else if averageGrade > 80 {
    gradeLetter = "B"
  } else if averageGrade > 70 {
    gradeLetter = "C"
  } else if averageGrade > 60 {
    gradeLetter = "D"
  } else {
    gradeLetter = "F"
  }
 
  return gradeLetter, averageGrade 
}
```

```go
func main() {
  var myMidterm, myFinal float32
  myMidterm = 89.4
  myFinal = 74.9
  var myAverage float32
  var myGrade string
  myGrade, myAverage = GPA(myMidterm, myFinal)
  fmt.Println(myAverage, myGrade) // Prints 82.12 B
}
```
### Deferring Resolution
We can delay a function call to the end of the current scope by using the `defer` keyword. `defer` tells Go to run a function, but at the end of the current function. This is useful for logging, file writing, and other utilities.

```go
func calculateTaxes(revenue, deductions, credits float64) float64 {
  defer fmt.Println("Taxes Calculated!")
  taxRate := .06143
  fmt.Println("Calculating Taxes")
 
  if deductions == 0 || credits == 0 {
    return revenue * taxRate
  }
 
 
  taxValue := (revenue - (deductions * credits)) * taxRate
  if taxValue >= 0 {
    return taxValue
  } else {
    return 0
  }
}
```

In the example above, the first print statement is being deferred. Normally, we would consider adding the print statement at the end of the function. But given that there are multiple `return` statements, instead of adding the same print statement before each return, `defer` can be used to print it regardless of when the function ends.

# Addresses and Pointers
Go is a _pass-by-value_ language, but it is possible to change values from different scopes using:
* Addresses
* Pointers
* Dereferencing
### Addresses
To find a variable's address we use the `&` operator followed by the variable name:
```go
x := "My very first address"
fmt.Println(&x) // Prints 0x414020
```

### Pointers
_Pointers_ are used to store addresses. 
```go
var pointerForInt *int
```
The `*` operator signifies that this variable will store an address and the `int` portion means that the address contains an integer value.

```go
var pointerForInt *int
 
minutes := 525600
 
pointerForInt = &minutes
 
fmt.Println(pointerForInt) // Prints 0xc000018038
```

Declare a pointer implicitly:
```go
minutes := 55
 
pointerForInt := &minutes
```

### Dereferencing
_Dereferencing_ or _indirecting_ refers to accessing the value at a given address. 
```go
lyrics := "Moments so dear" 
pointerForStr := &lyrics
 
*pointerForStr = "Journeys to plan" 
 
fmt.Println(lyrics) // Prints: Journeys to plan
```

### Changing Values in Different Scopes
By passing the value of a pointer, we can dereference the address and change the value in the function. The function call needs to pass in the address of the variable.
```go
func addHundred (numPtr *int) {
  *numPtr += 100
}
 
func main() {
  x := 1
  addHundred(&x)
  fmt.Println(x) // Prints 101
}
```