Hello World
A sample go program is show here.
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) string {
return "Hello, " + name + "!"
}
Run the program as below:
$ go run hello.go
This is the normal shape of a tiny Go program: main runs first, and fmt.Println writes output.
Variables
Normal Declaration:
var msg string
msg = "Hello"
Shortcut:
msg := "Hello"
This shows both var and the short := form. The short form is the one you will use most inside functions.
Constants
const Phi = 1.618
Use constants for values that should not change, such as fixed ratios, limits, or labels.
Strings
str := "Hello"
Multiline string
str := `Multiline
string`
This shows regular strings and raw multiline strings. Raw strings are handy when you want to keep formatting as written.
Numbers
Typical types
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias for uint8)
Other Types
var u uint = 7 // uint (unsigned)
var p float32 = 22.7 // 32-bit float
Go keeps numeric types explicit. The examples show the common defaults plus a few typed variants when precision or size matters.
Arrays
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}
This creates a fixed-size array. In day-to-day Go, slices are more common, but arrays are the underlying fixed-length value.
Pointers
func main () {
b := *getPointer()
fmt.Println("Value is", b)
func getPointer () (myPointer *int) {
a := 234
return &a
a := new(int)
*a = 234
Pointers point to a memory location of a variable. Go is fully garbage-collected.
Pointers let you work with the same value across functions without copying it. Go keeps them simpler than C by handling memory cleanup for you.
Type Conversion
i := 2
f := float64(i)
u := uint(i)
Go does not do many implicit numeric conversions, so converting types directly like this is normal.
Slice
slice := []int{2, 3, 4}
slice := []byte("Hello")
Slices are the main sequence type in Go. They are lightweight views over array-backed data and are used much more than arrays.
Condition
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}
if _, err := doThing(); err != nil {
fmt.Println("Uh oh")
This shows the normal if and else if flow in Go, plus the common if err != nil pattern for error handling.
Switch
switch day {
case "sunday":
// cases don't "fall through" by default!
fallthrough
case "saturday":
rest()
default:
work()
}
Go switch blocks are clean by default because cases do not fall through unless you ask for it explicitly.
Loop
for count := 0; count <= 10; count++ {
fmt.Println("My counter is at", count)
}
entry := []string{"Jack","John","Jones"}
for i, val := range entry {
fmt.Printf("At position %d, the character %s is present\n", i, val)
n := 0
x := 42
for n != x {
n := guess()
}
Go uses for for every looping style: counted loops, range loops, and condition-based loops.
Condition
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}
if _, err := doThing(); err != nil {
fmt.Println("Uh oh")
Despite the title here, this example is another Go conditional. It shows the same straight-line branching style used in most Go code.
Go Add
func add(param1, param2 int) int {
return param1 + param2
}
This just adds the two input numbers with the language’s normal arithmetic and returns the sum.
Go Add Border
func addBorder(picture []string) []string {
border := strings.Repeat("*", len(picture[0]))
result := make([]string, 0, len(picture)+2)
result = append(result, border)
for _, line := range picture {
result = append(result, "*"+line+"*")
}
result = append(result, border)
return result
}
This builds a new grid with a * border around every side. It adds a full top and bottom row, then wraps each existing row from left and right.
Go Adjacent Elements Product
func adjacentElementsProduct(inputArray []int) int {
max := inputArray[0] * inputArray[1]
for i := 0; i < len(inputArray)-1; i++ {
if p := inputArray[i] * inputArray[i+1]; p > max {
max = p
}
}
return max
}
This walks through neighboring values, multiplies each pair, and keeps the biggest product it finds.
Go Almost Magic Square
func almostMagicSquare(a []int) []int {
var grid [3][3]int
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
grid[i][j] = a[i*3+j]
}
}
rowSum := make([]int, 3)
colSum := make([]int, 3)
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
rowSum[i] += grid[i][j]
colSum[i] += grid[j][i]
}
}
maxSum := 0
for k, v := range rowSum {
maxSum = max(maxSum, v, colSum[k])
}
for i, j := 0, 0; i < 3 && j < 3; {
diff := min(maxSum-rowSum[i], maxSum-colSum[j])
grid[i][j] += diff
rowSum[i] += diff
colSum[j] += diff
if rowSum[i] == maxSum {
i++
}
if colSum[j] == maxSum {
j++
}
}
result := make([]int, 0, 9)
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
result = append(result, grid[i][j])
}
}
return result
}
This adjusts the matrix toward a matching target sum so the rows and columns line up more like a magic square.
Go Are Equally Strong
func areEquallyStrong(yourLeft, yourRight, friendsLeft, friendsRight int) bool {
return max(yourRight, yourLeft) == max(friendsLeft, friendsRight) &&
min(yourLeft, yourRight) == min(friendsRight, friendsLeft)
}
This compares each person’s strongest and weakest arm. If both pairs match, the result is true.
Go Array Change
func arrayChange(a []int) int {
moves := 0
for k := 0; k < len(a)-1; k++ {
if a[k] >= a[k+1] {
diff := a[k] - a[k+1] + 1
a[k+1] += diff
moves += diff
}
}
return moves
}
This moves left to right and bumps values only when needed so the array becomes strictly increasing.