Core Programming
Examples in
Go
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
/*
Go supports following built-in basic types:
one boolean built-in boolean type: bool.
11 built-in integer numeric types: int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, and uintptr.
two built-in floating-point numeric types: float32 and float64.
two built-in complex numeric types: complex64 and complex128.
one built-in string type: string
*/
A pointer is a programming language object that stores the memory address of another value located in computer memory.
package main
import "fmt"
func zeroval(ival int) {
ival = 0
}
func zeroptr(iptr *int) {
*iptr = 0
}
func main() {
i := 1
fmt.Println("initial:", i)
zeroval(i)
fmt.Println("zeroval:", i)
zeroptr(&i)
fmt.Println("zeroptr:", i)
fmt.Println("pointer:", &i)
}
// The iota keyword represents successive integer constants 0, 1, 2,…
// It resets to 0 whenever the word const appears in the source code,
// and increments after each const specification.
const (
C0 = iota
C1
C2
)
fmt.Println(C0, C1, C2) // "0 1 2"
// To start a list of constants at 1 instead of 0, you can use iota in an arithmetic expression.
const (
C1 = iota + 1
C2
C3
)
fmt.Println(C1, C2, C3) // "1 2 3"
const (
C1 = iota + 1
_
C3
C4
)
fmt.Println(C1, C3, C4) // "1 3 4"
// Complete enum type with strings [best practice]
type Direction int
const (
North Direction = iota
East
South
West
)
func (d Direction) String() string {
return [...]string{"North", "East", "South", "West"}[d]
}
package main
import "fmt"
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(7))
}
Defer is used to ensure that a function call is performed later in a program’s execution, usually for purposes of cleanup. defer is often used where e.g. ensure and finally would be used in other languages.
package main
import (
"fmt"
"os"
)
func main() {
// Immediately after getting a file object with createFile, we defer the closing of that file with closeFile.
// This will be executed at the end of the enclosing function (main), after writeFile has finished.
f := createFile("/tmp/defer.txt")
defer closeFile(f)
writeFile(f)
}
func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}
func closeFile(f *os.File) {
fmt.Println("closing")
err := f.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
Parsing numbers from strings is a basic but common task in many programs; here’s how to do it in Go.
package main
import (
"fmt"
"strconv"
)
func main() {
// With ParseFloat, this 64 tells how many bits of precision to parse.
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f)
// For ParseInt, the 0 means infer the base from the string.
// 64 requires that the result fit in 64 bits.
i, _ := strconv.ParseInt("123", 0, 64)
fmt.Println(i)
// ParseInt will recognize hex-formatted numbers.
d, _ := strconv.ParseInt("0x1c8", 0, 64)
fmt.Println(d)
u, _ := strconv.ParseUint("789", 0, 64)
fmt.Println(u)
// Atoi is a convenience function for basic base-10 int parsing.
k, _ := strconv.Atoi("135")
fmt.Println(k)
_, e := strconv.Atoi("wat")
fmt.Println(e)
}
package main
import "fmt"
func main() {
var a [5]int
fmt.Println("emp:", a)
a[4] = 100
fmt.Println("set:", a)
fmt.Println("get:", a[4])
fmt.Println("len:", len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println("dcl:", b)
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
}
package main
import "fmt"
type rect struct {
width, height int
}
func (r *rect) area() int {
return r.width * r.height
}
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
func main() {
r := rect{width: 10, height: 5}
fmt.Println("area: ", r.area())
fmt.Println("perim:", r.perim())
rp := &r
fmt.Println("area: ", rp.area())
fmt.Println("perim:", rp.perim())
}
package main
import (
"fmt"
"math"
)
type geometry interface {
area() float64
perim() float64
}
type rect struct {
width, height float64
}
type circle struct {
radius float64
}
func (r rect) area() float64 {
return r.width * r.height
}
func (r rect) perim() float64 {
return 2*r.width + 2*r.height
}
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
return 2 * math.Pi * c.radius
}
func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
fmt.Println(g.perim())
}
func main() {
r := rect{width: 3, height: 4}
c := circle{radius: 5}
measure(r)
measure(c)
}
You can return a value after recovering a function by using named result parameters.
package main
import "fmt"
func main() {
fmt.Println("Returned:", MyFunc())
}
func MyFunc() (ret string) {
defer func() {
if r := recover(); r != nil {
ret = fmt.Sprintf("was panic, recovered value: %v", r)
}
}()
panic("test")
return "Normal Return Value"
}
/*
Up to (Go 1.13), Go has only 25 keywords:
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
*/