Golang: Structs Methods and Interface

Go Struct, Methods and Embedding example

package main

import "fmt"

type User struct {
	name, address string
}

type Employee struct {
	level  int
	salary int
	user   User // Embedding
}

/**
 * Greating for User
 */
func (u User) Greeting() string {
	return fmt.Sprintf("Dear %s %s", u.name, u.address)
}

/**
 * Greating for User
 */
func (e Employee) Greeting() string {
	return fmt.Sprintf("Your level %d, Your salary %d", e.level, e.salary)
}

func main() {
	user := User{"Yazid", "Jalan munukan no.19"}

	fmt.Println(user.Greeting())

	employee := Employee{1, 2000, user}

	fmt.Println(employee.user.Greeting())
	fmt.Println(employee.Greeting())
}

Using Pointer to keep the lowest amount of structs per file

package main

import (
	"fmt"
)

type User struct {
	FirstName, LastName string
}

func (u *User) Greeting() string {
	return fmt.Sprintf("Dear %s %s", u.FirstName, u.LastName)
}
func main() {
	u := &User{"Yusuf", "Ibrahim"}
	fmt.Println(u.Greeting())
}

Golang Interface Example

package main

import (
	"fmt"
)

type User struct {
	FirstName, LastName, address string
}

func (u *User) Name() string {
	return fmt.Sprintf("%s %s", u.FirstName, u.LastName)
}

func (u *User) Address() string {
	return fmt.Sprintf("%s", u.address)
}

type Customer struct {
	Id                int
	FullName, address string
}

func (c *Customer) Name() string {
	return c.FullName
}

func (c *Customer) Address() string {
	return fmt.Sprintf("%s", c.address)
}

type Namer interface {
	Name() string
	Address() string
}

func Greet(n Namer) string {
	return fmt.Sprintf("Dear %s at %s", n.Name(), n.Address())
}
func main() {
	u := &User{"Matt", "Aimonetti", "jalan Banda"}
	fmt.Println(Greet(u))

	c := &Customer{42, "Francesc", "jalan Banda"}
	fmt.Println(Greet(c))
}

Advertisements

Golang: Map, Hashes, Dictionary

Golang Maps are similar to what other language call ‘dictionaries’ or ‘hashes’.

 

package main

import "fmt"

var names = map[string]int{"Katrina": 10, "Evan": 11, "Neil": 12}

func main() {
    //  fmt.Printf("%#v", names)

    for x, _ := range names {
        fmt.Println(x)
    }
    // Output:
    // Katrina
    // Evan
    // Neil

    for _, name := range names {
        fmt.Println(name)
    }
    // Output:
    // 10
    // 11
    // 12

    for x, name := range names {
        fmt.Printf("%s : %d \n", x, name)
    }
    // Output
    // Katrina : 10
    // Evan : 11
    // Neil : 12

}

Add / Append new data to a map


package main

import "fmt"

func main() {
	names := make(map[string]int)
	//	fmt.Printf("%#v", names)

	names["jhony"] = 1
	names["beta"] = 2

	for x, name := range names {
		fmt.Printf("%s : %d \n", x, name)
	}

}

Collection of objects


package main

import "fmt"

type Person struct {
	name, address string
}

func main() {
	jelemas := make(map[string]Person)

	jelemas["Yoesoff"] = Person{"yusuf", "Jl. Wakwau no.09"}
	jelemas["Yuka"] = Person{"gokana", "Jl. Wakwau no.90"}
	jelemas["Mumun"] = Person{"pocong", "Jl. Wakwau no.99"}

	//	fmt.Printf("%#v", names)
	for x, wong := range jelemas {
		fmt.Printf("%s : %s (%s) \n", x, wong.name, wong.address)
	}

	// Output
	// Yuka : gokana (Jl. Wakwau no.90)
	// Mumun : pocong (Jl. Wakwau no.99)
	// Yoesoff : yusuf (Jl. Wakwau no.09) 

}

Remove / Delete item from map


package main

import "fmt"

type Person struct {
	name, address string
}

func main() {
	jelemas := make(map[string]Person)

	jelemas["Yoesoff"] = Person{"yusuf", "Jl. Wakwau no.09"}
	jelemas["Yuka"] = Person{"gokana", "Jl. Wakwau no.90"}
	jelemas["Mumun"] = Person{"pocong", "Jl. Wakwau no.99"}

	//	fmt.Printf("%#v", names)
	for x, wong := range jelemas {
		fmt.Printf("%s : %s (%s) \n", x, wong.name, wong.address)
	}

	// Output
	// Yuka : gokana (Jl. Wakwau no.90)
	// Mumun : pocong (Jl. Wakwau no.99)
	// Yoesoff : yusuf (Jl. Wakwau no.09)

	delete(jelemas, "Mumun")

	fmt.Println("Delete Mumun (Because he is scary)")
	for x, wong := range jelemas {
		fmt.Printf("%s : %s (%s) \n", x, wong.name, wong.address)
	}

	// Output
	// Delete Mumun (Because he is scary)
	// Yoesoff : yusuf (Jl. Wakwau no.09)
	// Yuka : gokana (Jl. Wakwau no.90)

}

Check Element existence in a map


	// Check Element
	_, ok := jelemas["Yuka"]

	fmt.Println(ok)

	_, ok = jelemas["Mumun"]

	fmt.Println(ok)

Golang Iteration/loop: Break & continue


package main

import "fmt"

var pows = []int{1, 2, 4, 8, 16, 32, 64, 128}
var users = []string{"yuna", "yuni", "yuka", "deisy", "Miyem", "Jhony", "Merry", "Toni"}

func main() {
	for x, value := range pows {

		fmt.Println(x, ":", value)

		if value >= 16 {
			// After x is greater or equal to 16 stop the iterate
			break
		}
	}

	for x, value := range pows {

		fmt.Println(x, ":", value)

		if value >= 16 {
			continue
		}

		// After x is greater or equal to 16 do  not print this
		fmt.Println("------")
	}

}

Golang Output

0 : 1

1 : 2

2 : 4

3 : 8

4 : 16

 

0 : 1

——

1 : 2

——

2 : 4

——

3 : 8

——

4 : 16

5 : 32

6 : 64

7 : 128

Success: process exited with code 0.

Golang Data Collection: “Foreach” iterates through all entries of an array using range

A “for” statement with a “range” clause iterates through all entries of an array, slice, string or map, or values received on a channel. For each entry it assigns iteration values to corresponding iteration variables and then executes the block.

there is no foreach in Golang, But using a for statement with range clause we can iterate through all entries of an array, slice, string or map, or values received on a channel.

The following example shows how to use the range operator in a for loop to implement a foreach loop in Golang:


package main

import "fmt"

var pows = []int{1, 2, 4, 8, 16, 32, 64, 128}
var users = []string{"yuna", "yuni", "yuka", "deisy", "Miyem", "Jhony", "Merry", "Toni"}

func main() {
	for x, value := range pows {
		fmt.Println(x, ":", value)
	}

	for x, user := range users {
		fmt.Println(x, ":", user)
	}
}

Go Output

0 : 1

1 : 2

2 : 4

3 : 8

4 : 16

5 : 32

6 : 64

7 : 128

0 : yuna

 

1 : yuni

2 : yuka

3 : deisy

4 : Miyem

5 : Jhony

6 : Merry

7 : Toni

Success: process exited with code 0.

gommu1.png

Golang: Collection

In this post I write down my experience regarding data collection in Golang, basically collection  is a grouping of some variable number of data items (Examples of collections include lists, sets, multisets, trees and graphs.).

Golang Array Example:

package main

import "fmt"

var (
	a [3]string
)

func main() {

	a[0] = "Hi"
	a[1] = "little"
	a[2] = "Buddy"

	fmt.Println(a[0], a[1])
	fmt.Printf("%s %s %s \n", a[0], a[1], a[2])
	fmt.Println(a)
}

Go Output:

Hi little

Hi little Buddy

[Hi little Buddy]

Golang Multi-dimensional arrays by example:


package main

import "fmt"

func main() {
	var a [2][3]string
	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			a[i][j] = fmt.Sprintf("row %d - column %d", i+1, j+1)
		}
	}

	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			fmt.Println(a[i][j])
		}
	}

	fmt.Println("------------------------")

	fmt.Printf("%q", a)
}

Go Output:

row 1 – column 1

row 1 – column 2

row 1 – column 3

row 2 – column 1

row 2 – column 2

row 2 – column 3

————————

[[“row 1 – column 1” “row 1 – column 2” “row 1 – column 3”] [“row 2 – column 1” “row 2 – column 2” “row 2 – column 3”]]

Set the array entries  while declare the array


package main

import "fmt"

func main() {

	a := []string{"aaaaa", "bbbbb"}
	a = append(a, "ccccc")

	fmt.Println(a[0]) // Index 0
	fmt.Println(a[1]) // Index 0
	fmt.Println(a[2]) // Index 0

	fmt.Printf("%s\n", a) // Print as string
	fmt.Printf("%q", a)   // Print as array collection
}

Go Output:

aaaaa

bbbbb

ccccc

[aaaaa bbbbb ccccc]

[“aaaaa” “bbbbb” “ccccc”]

Common errors related array in Golang:

  • Assign value to the undefined / invalid array index

./test.go:14: invalid array index 3 (out of bounds for 3-element array)

Error: process exited with code 2.

  • Assign value to undefined variable

./test.go:13: undefined: a

Error: process exited with code 2.

  • Index out of range

Just trying to define the array to be like this:


var (
	a []string
)

And the result is like this:

panic: runtime error: index out of range

goroutine 1 [running]:

panic(0x45afa0, 0xc42000a1e0)

/usr/local/go/src/runtime/panic.go:500 +0x1a1

main.main()

/home/yusuf/go-learn2/src/github.com/yoesoff/test_ide/test.go:9 +0x3a

Error: process exited with code 2.

Slicing a slice


package main

import "fmt"

func main() {
	mySlice := []int{11, 12, 13, 14, 15, 16}

	fmt.Println(mySlice[0])   // 11
	fmt.Println(mySlice[0:3]) // [11, 12,13]
	fmt.Println(mySlice[0:2]) // [11, 12]

	// Having same output with above code
	fmt.Println(mySlice[0])  // 11
	fmt.Println(mySlice[:3]) // [11, 12,13]
	fmt.Println(mySlice[:2]) // [11, 12]

	fmt.Println(mySlice[0:]) // [11 12 13 14 15 16]
	fmt.Println(mySlice[1:]) // [12 13 14 15 16]
	fmt.Println(mySlice[2:]) // [13 14 15 16]
	fmt.Println(mySlice[3:]) //[14 15 16]

}

Go Output:

11

[11 12 13]

[11 12]

11

[11 12 13]

[11 12]

[11 12 13 14 15 16]

[12 13 14 15 16]

[13 14 15 16]

[14 15 16]

Success: process exited with code 0.

Another Slicing  slice example


 package main

import "fmt"

func main() {
	mySlice := []int{11, 12, 13, 14, 15, 16}

	fmt.Println(mySlice[0:6])
	fmt.Println(mySlice[0:5])
	fmt.Println(mySlice[0:4])
	fmt.Println(mySlice[0:3])
	fmt.Println(mySlice[0:2])
	fmt.Println(mySlice[0:1])

	fmt.Println(mySlice[5:6])
	fmt.Println(mySlice[4:6])
	fmt.Println(mySlice[3:6])
	fmt.Println(mySlice[2:6])
	fmt.Println(mySlice[1:6])
	fmt.Println(mySlice[0:6])
}

Go Output:

[11 12 13 14 15 16]

[11 12 13 14 15]

[11 12 13 14]

[11 12 13]

[11 12]

[11]

[16]

[15 16]

[14 15 16]

[13 14 15 16]

[12 13 14 15 16]

[11 12 13 14 15 16]

Appending to a slice


package main

import "fmt"

func main() {
	// Code below won't work
	//	cities := []string{}
	//	cities[0] = "Santa Monica"

	// This code is working well
	cities := []string{}
	cities = append(cities, "Santa Monica")
	fmt.Println(cities)
}

Go Output:

[Santa Monica]

Success: process exited with code 0.

Append more


//append more
cities = append(cities, "San Diego", "Mountain View", "Jakarta", "Bali", "Trenggalek")
fmt.Printf("%q", cities)

Go Output:

[“Santa Monica” “San Diego” “Mountain View” “Jakarta” “Bali” “Trenggalek”]

Success: process exited with code 0.

check the length of a slice by using len()

cities = append(cities, "San Diego", "Mountain View", "Jakarta", "Bali", "Trenggalek")
fmt.Printf("%d", len(cities))

Go Output:

5

Another  exciting Example about slice

Go slices, usage and internals
Effective Go – slices
Append function documentation
Slice tricks
Effective Go – slices
Effective Go – two-dimensional slices
Go by example – slices

Common errors related slice in Golang:

  • slice bounds out of range

panic: runtime error: slice bounds out of range

goroutine 1 [running]:

panic(0x47a8e0, 0xc42000a1f0)

/usr/local/go/src/runtime/panic.go:500 +0x1a1

main.main()

/home/yusuf/go-learn2/src/github.com/yoesoff/hello/hello.go:20 +0x53

Error above caused by this:

mySlice := []int{11, 12, 13, 14, 15, 16}

fmt.Println(mySlice[3:12]) // [14 15 16 undefined …]

  • slice bounds out of range

panic: runtime error: slice bounds out of range

goroutine 1 [running]:

panic(0x47a8e0, 0xc42000a1f0)

/usr/local/go/src/runtime/panic.go:500 +0x1a1

main.main()

/home/yusuf/go-learn2/src/github.com/yoesoff/hello/hello.go:8 +0x53

Error: process exited with code 2.

mySlice := []int{11, 12, 13, 14, 15, 16}

fmt.Println(mySlice[0:7000])  // max is 6

Golang: The easy way to understand Golang Pointer thru example

Pointers reference a location in memory where a value is stored rather than the value itself. (They point to something else)

I write down my learning experiences about  Golang’s Pointer using easy way, here is my note:

The first step we have to understand  & and * operators:

 & and * Operators :

package main

import "fmt"

func do(x *int) {
	*x = 99 // Update x value
}

func main() {
	x := 5

	do(&x) // pass address of x

	fmt.Println(x) // The value updated through pointer
}

Output:

99

More example about pointer and operators

package main

import "fmt"

func do(x *int) {
	*x = 99
}

func main() {
	x := 5

	y := &x

	fmt.Println(&x) // Address of x
	fmt.Println(y)  // Address of x
	fmt.Println(&y) // Address of y that stores x Address

	do(y)

	fmt.Println(x)
}

Output:

0xc42000a3b0 // Address of x

0xc42000a3b0 // Address of x

0xc420032020 // Address of y that stores x Address

99  // x new value after updated thru pointer

Print x value thru pointer y:


package main

import "fmt"

func do(x *int) {
	*x = 99
}

func main() {
	x := 5

	y := &x

	fmt.Println(*y)
}

Output:

5

Another example: https://tour.golang.org/moretypes/1

Golang: Structs collection of fields properties

Explanation regarding Struct in Golang:

  1. A struct is a collection of fields/properties.
    type Bootcamp struct {
        // Latitude of the event
        Lat float64
        // Longitude of the event
        Lon float64
        // Date of the event
        Date time.Time
    }
    
  2. You can define new types as structs or interfaces
    type Bootcamp struct {
        // Latitude of the event
        Lat float64
        // Longitude of the event
        Lon float64
        // Date of the event
        Date time.Time
    }
    
    type Namer interface {
        Name() string
    }
    
    type Reader interface {
        Read(b []byte) (n int, err error)
    }
    
    type Writer interface {
        Write(b []byte) (n int, err error)
    }
    
    type ReadWriter interface {
        Reader
        Writer
    }
    
    
  3. you can think of a struct to be a light class that supports composition but not inheritance.
    package main
    
    import "fmt"
    
    type User struct {
        Id    int
        Name, Location string
    }
    type Player struct {
        User
        GameId int
    }
    
    func main() {
        p := Player{
            User{Id: 42, Name: "Matt", Location: "LA"},
            90404,
        }
        fmt.Printf("Id: %d, Name: %s, Location: %s, Game id: %d\n",
            p.Id, p.Name, p.Location, p.GameId)
        // Directly set a field defined on the Player struct
        p.Id = 11
        fmt.Printf("%+v", p)
    }
    
  4. You don’t need to define getters and setters on struct fields, they can be accessed automatically.
    event := Bootcamp{
        Lat: 34.012836,
        Lon: -118.495338,
    }
    event.Date = time.Now()
    fmt.Printf("Event on %s, location (%f, %f)", event.Date, event.Lat, event.Lon)
    
  5. However, note that only exported fields (capitalized) can be accessed from outside of a package.
  6. A struct literal sets a newly allocated struct value by listing the values of its fields.
  7. You can list just a subset of fields by using the “Name:” syntax (the order of named fields is irrelevant when using this syntax).
     event := Bootcamp{
        Lat: 34.012836,
        Lon: -118.495338,
    }
  8. The special prefix & constructs a pointer to a newly allocated struct.

COMPOSITION

Golang Composition Sample Code 1:

package main

import "fmt"

type User struct {
	Id       int
	Name     string
	Location string
}

type Player struct {
	User
	Location string
	GameId   int
}

func main() {
	p := Player{}
	p.Id = 42
	p.Name = "Matt"
	p.Location = "LA"
	p.GameId = 90404
	fmt.Printf("%+v", p)
}

Golang Composition Sample Code 2 (The other option is to use a Google Language struct literal:) :

package main

import "fmt"

type User struct {
	Id             int
	Name, Location string
}

type Player struct {
	User
	GameId uint
}

func main() {
	p := Player{
		User{Id: 42, Name: "Matt", Location: "LA"},
		9004,
	}
	fmt.Printf("%+v", p)
}

Golang: Type Conversion and Type Assertion

This note is talking about Golang Type Conversion and Assertion

Type Conversion Sample 1:

package main

import "fmt"

var (
	i int
	f float64
	u uint
)

func main() {

	i := 42
	f := float64(i)
	u := uint(f)

	fmt.Printf("%d | %f | %d", i, f, u)
}

Output:

42 | 42.000000 | 42

Type Assertion Sample 2:

package main

package main

import (
	"fmt"
	"time"
)

func timeMap(y interface{}) {
	z, ok := y.(map[string]interface{})
	if ok {
		z["updated_at"] = time.Now()
	}
}

func main() {
	foo := map[string]interface{}{
		"Matt": 42,
	}
	timeMap(foo)
	fmt.Println(foo)
}

Output:

map[Matt:42 updated_at:2016-12-25 12:08:55.846672892 +0700 WIB]

*In this step I am still not sure about what the code actually does

Golang: Mutability and pass variable as reference using a pointer

In this note I will show you about mutating a variable value using pointer in Golang Programming:

Sample 1:


package main

import "fmt"

type Artist struct {
    Name, Genre string
    Songs       int
}

func newRelease(a Artist) int {
    a.Songs++
    return a.Songs
}

func main() {
    me := Artist{Name: "Matt", Genre: "Electro", Songs: 42}
    fmt.Printf("%s released their %dth song\n", me.Name, newRelease(me))
    fmt.Printf("%s has a total of %d songs", me.Name, me.Songs)
}

Output:

output1.png

Output text:

Matt released their 43th song

Matt has a total of 42 songs

Sample 2:


package main

import "fmt"

type Artist struct {
    Name, Genre string
    Songs       int
}

func newRelease(a *Artist) int {
    a.Songs++
    return a.Songs
}

func main() {
    me := &Artist{Name: "Matt", Genre: "Electro", Songs: 42}
    fmt.Printf("%s released their %dth song\n", me.Name, newRelease(me))
    fmt.Printf("%s has a total of %d songs", me.Name, me.Songs)
}

Output:

output2.png

Output text:

Matt released their 43th song

Matt has a total of 43 songs