Construct, Run and Build

mkdir -p <project-name>
cd <project-name>
go mod init <project-name> # Construct
 
go run <filename>.go # Run
 
go build <filename>  # Build
./<filename>         # Run

Values

String, integer, float, boolean and so on. And their operators.

Variable

  • Strong typed
  • Use keyword var to declare 1 or more variables
  • Specify the type behind variable(s)‘s name
  • Go will infer the type of initialized variables
  • Variables declared without a corresponding initialization are zero-valued
  • The := syntax is shorthand for declaring and initializing a variable. This syntax is only available inside functions.
package main
import "fmt"
func main() {
    var a bool           // The value of a is `false`
    var b, c int = 1, 2  // Omit the type is recommended since Go can infer the type
    var d = 12.0
    e := "string" // Equals to `var e string = "string", var e = "string"` 
 
    fmt.Println(a, b, c, d, e) // false 1 2 12 string
}

Constants

  • const declares a constant value
  • A const statement can appear both outside and inside a function body.
  • Constant expressions perform arithmetic with arbitrary precision.
  • A numeric constant has no type until it’s given one.
  • A number can be given a type by using it in a context that requires one, such as a variable assignment or function call.
package main
import (
    "fmt"
    "math"
)
const s string = "constant string"
func main() {
    const big = 2e30
    small := big
    fmt.Printf("Type: %T\n", small) // `small` has a type of `float64`
    fmt.Println(s, big, int64(big/2e20), math.Sin(big/2e20))
    // Constant can get a type by an explicit conversion, a variable assignment or function call(`math.Sin` expects `float64`).
}
/*
Type: float64
constant string 2e+30 10000000000 -0.48750602508751073
*/

Control Stream

Loop

for is Go’s only looping construct.

package main
import "fmt"
func main() {
    i := 0
    for i < 3 {                // Basic type with a single condition
        fmt.Println(i)
        i++
    }
    for j := 0; j < 3; j++ {   // Classic type
        fmt.Println(j)
    }
    for j := range 3 {         // Modern way to repeat specified times  
        fmt.Println(j)
    }
    for {                      // Infinity loop
        fmt.Println("Infinity")
        break
    }
    for n := range 6 {
        if n % 2 == 0 {
            continue           // Break and continue is supported
        }
        fmt.Println(n)
    }
}
/*
0
1
2
0
1
2
0
1
2
Infinity
1
3
5
*/

If-Else

There is no ternary if ?: in Go, so you’ll need to use a full if statement even for basic conditions.

package main
import "fmt"
func main() {
    // Just like other language, but don’t need parentheses around conditions in Go, but that the braces are required.
    if 8%2 == 0 && 7%2 != 0 {
        fmt.Println("8 is even and 7 is odd")
    } else if 8%2 != 0 || 7%2 == 0 {
        fmt.Println("Something is wrong")
    } else {
        fmt.Println("Oops...")
    }
    // A statement can precede conditionals; any variables declared in this statement are **available in the current and all subsequent branches**.
    foo := 100
    if bar := foo; bar < 100 {
        fmt.Println(bar, "is smaller than 100")
    } else if bar == 100 {
        fmt.Println(bar, "equals to 100")
    } else {
        fmt.Println(bar, "is bigger than 100")
    }
}
/*
8 is even and 7 is odd
100 equals to 100
*/

Switch

package main
import (
    "fmt"
    "time"
)
func main() {
    switch time.Now().Weekday() { 
    case time.Saturday, time.Sunday:// Multiple conditions
        fmt.Println("Weekend")
    default:
        fmt.Println("Weekday")
    }
 
    t := time.Now()
    switch {                        // `switch` without an expression
    case t.Hour() < 12:             // Used as `if-else` statement
        fmt.Println("AM")
    default:
        fmt.Println("PM")
    }
 
    whichType := func(i interface{}) { 
    // Type switch, used to judge type, like `instanceof` in Java
        switch t := i.(type) { // `:=` is supported as `if-else`
        case bool:
            fmt.Println("Bool")
        case int:
            fmt.Println("Int")
        default:
            fmt.Println("Value: ", t)
            fmt.Printf("Unknown type %T\n", t)
        }
    }
    whichType(1)
    whichType(1.2)
    whichType(true)
}
/*
two
Weekday
AM
Int
Value:  1.2
Unknown type float64
Bool
*/

The essence of switch in Go is to compare.

switch <Precede>; <Value> {
case <Condition>:
    ...
}

Equals that <value> == <Condition>, so:

age := getAge()
switch age {
case 18:    // Judge: age == 18
    fmt.Println("Just become an adult")
default: 
    fmt.Println("Else") }
    
switch age := getAge(); { // IMPORTANT: SEMICOLON
// Equals to:
// switch age := getAge(); true {
case age < 18:            // true == age < 18
    fmt.Println("Underaged")
case age >= 18:           // true == age >= 18
    fmt.Println("Adult") 
}
 
/* Equivalent */
switch age := getAge(); age {
case 18: // ... 
} // Better, idiomatic
 
switch age := getAge(); { 
case age == 18: // ... 
}