SlideShare a Scribd company logo
1 of 165
Download to read offline
Copyright
Go Programming by Example
Agus Kurniawan
1st Edition, 2015
Copyright © 2015 Agus Kurniawan
* Cover photo is credit to Fajar Ramadhany, Bataviasoft, http://bataviasoft.com/.
** Go logo is taken from https://blog.golang.org/gopher .
Table of Contents
Copyright
Preface
1. Development Environment
1.1 Installation
1.2 Development Tools
1.3 Hello World
1.4 Go Packages
2. Go Programming Language
2.1 Common Rule
2.2 Variables
2.2.1 Declaring Variable
2.2.2 Assigning Variables
2.2.3 Demo
2.3 Comment
2.4 Arithmetic Operations
2.5 Mathematical Functions
2.6 Increment and Decrement
2.7 Getting Input from Keyboard
2.8 Comparison Operators
2.9 Logical Operators
2.10 Decision
2.10.1 if..then
2.10.2 switch..case
2.11 Iteration - for
2.12 Iteration - while
2.13 break and continue
3. Arrays, Slices and Maps
3.1 Array
3.2 Slice
3.3 Map
4. Functions
4.1 Creating A Simple Function
4.2 Function with Parameters
4.3 Function with Returning Value
4.4 Function with Multiple Returning Values
4.5 Function with Multiple Parameters and Returning Value
4.6 Closure Function
4.7 Recursion Function
4.8 Testing
5. Pointers
5.1 Pointer in Go
5.2 Demo: Singly Linked List
6. Structs and Methods
6.1 Structs
6.2 Methods
7. String Operations
7.1 Getting Started
7.2 Concatenating Strings
7.3 String To Numeric
7.4 Numeric to String
7.5 String Parser
7.6 Check String Data Length
7.7 Copy Data
7.8 Upper and Lower Case Characters
7.9 Testing A Program
8. File Operations
8.1 Getting Started
8.2 Writing Data Into A File
8.3 Reading Data From A File
8.4 Writing All
9. Error Handling and Logging
9.1 Error Handling
9.2 defer, panic(), and recover()
9.3 try..catch
9.4 Logging
10. Building Own Go Package
10.1 Creating Simple Module
10.2 Building Own Package
11. Concurrency
11.1 Getting Started
11.2 Goroutines
11.3 Synchronizing Goroutines
11.4 Channels
12. Encoding
12.1 Getting Started
12.2 Encoding Base64
12.3 Hexadecimal
12.4 JSON
12.5 XML
12.6 CSV
13. Hashing and Cryptography
13.1 Getting Started
13.2 Hashing
13.2.1 Hashing with MD5
13.2.2 Hashing with SHA256
13.2.3 Hashing with Key Using HMAC
13.2.4 Testing
13.3 Cryptography
13.3.1 Symmetric Cryptography
13.3.2 Asymmetric Cryptography
14. Database Programming
14.1 Database for Go
14.2 MySQL Driver for Go
14.3 Testing Connection
14.4 Querying
15. Socket Programming
15.1 Socket Module
15.2 Hello World
15.3 Client/Server Socket
15.3.1 Server Socket
15.3.2 Client Socket
15.3.3 Testing
Source Code
Contact
Preface
Go was created by Robert Griesemer, Rob Pike, and Ken Thompson at Google in 2007.
This book is a reference to the Go programming language. It describes all the elements
of the language and illustrates their use with code examples.
Agus Kurniawan
Berlin & Depok, February 2015
1. Development Environment
This chapter explains introduction of Go. The official web of Go could be found
on https://golang.org/. What is Go? Based on information from website, we could know
what it is. Go is an open source programming language that makes it easy to build simple,
reliable, and efficient software.
1.1 Installation
Installation of Go application is easy. For Windows and Mac Platform, you download
setup file from Go website, http://golang.org/doc/install. Run it and follow installation
commands.
The next step is to configure GOROOT path. For Windows platform, you can add
GOROOT variable on Environment Variables. For Mac/Linux, you can it on your bash
profile.
For Windows platform, you can add GO installation path, for instance my Go installation
path is c:/go/bin, into PATH variable on Environment Variables.
After configured, you can verify Go version by typing this command on your Terminal or
CMD for Windows.
$ go version
A sample output can be seen in Figure below, Mac platform.
The output of program on Windows platform.
1.2 Development Tools
Basically, you can use any text editor to write Go code. The following is a list of text
editor:
vim
nano
Intellij IDEA, https://www.jetbrains.com/idea/
Sublime text, http://www.sublimetext.com/
A sample screenshot for Intellij IDEA is shown in Figure below.
1.3 Hello World
How to get started with Go? well, it is easy. Firstly, create a folder, called hello.
$ mkdir hello
$ cd hello
Then, create a file, called main.go, on the hello folder. Write this code for main.go file.
package main
import "fmt"
func main() {
fmt.Println("Hello, go!")
}
Save this file. Then, back to your Terminal. You can build and run it.
$ go build
$ go run main.go
In this case, it will generate an executable file based on your platform.
A sample program output can be seen in Figure below.
1.4 Go Packages
There are a lot of Go packages that you can use. The list of Go packages can seen on this
link https://golang.org/pkg/. In this book, we will explore some Go standard packages. We
also try to build own Go package.
2. Go Programming Language
This chapter explains the basic of Go programming language.
2.1 Common Rule
Go language uses “C family” as primary language but we don’t write “;” at the end of
syntax. Here is the syntax rule:
syntax_code1
syntax_code2
syntax_code3
2.2 Variables
In this section, we explore how to define a variable and assign its value.
2.2.1 Declaring Variable
To declare a variable called myvar and data type is data_type1, you can write the
following script:
var myvar data_type1
The following is a sample script to declare some variables.
var str string
var n, m int
var mn float32
We also can define multiple variables as follows.
var (
name string
email string
age int
)
Once declared, these variables can be used to store any type data.
2.2.2 Assigning Variables
Variable that you already declare can be assigned by a value. It can done using the equals
sign (=). For example, variable str will assign a string value “Hello World”, you would
write this:
str = "Hello World"
n = 10
m = 50
mn = 2.45
We also can declare a variable and assign its value.
var city string = "London"
var x int = 100
Another option, we can declare a variable with defining data type using := syntax. Assign
it with a value.
country := "DE"
val := 15
2.2.3 Demo
For illustration for declaring variables using Go, create a folder, called vardemo. Then,
create a file, called main.go.
Write the following script for main.go.
package main
import "fmt"
func main() {
// declare variables
var str string
var n, m int
var mn float32
// assign values
str = "Hello World"
n = 10
m = 50
mn = 2.45
fmt.Println("value of str= ",str)
fmt.Println("value of n= ",n)
fmt.Println("value of m= ",m)
fmt.Println("value of mn= ",mn)
// declare and assign values to variables
var city string = "London"
var x int = 100
fmt.Println("value of city= ",city)
fmt.Println("value of x= ",x)
// declare variable with defining its type
country := "DE"
val := 15
fmt.Println("value of country= ",country)
fmt.Println("value of val= ",val)
// define multiple variables
var (
name string
email string
age int
)
name = "john"
email = "john@email.com"
age = 27
fmt.Println(name)
fmt.Println(email)
fmt.Println(age)
}
Save this file.
Then, try to build and run it.
$ cd vardemo
$ go build
$ go run main.go
A sample output can be seen in Figure below.
2.3 Comment
You may explain how to work on your code with writing comments. To do it, you can use
// and /* */ syntax. Here is sample code:
// declare variables
var str string
var n, m int
var mn float32
// assign values
str = "Hello World"
n = 10
m = 50
mn = 2.45
/* print the result */
fmt.Println("value of str= ",str)
2.4 Arithmetic Operations
Go supports the same four basic arithmetic operations such as addition, subtraction,
multiplication, and division. For testing, create a folder arithdemo. Then, create a file,
called main.go.
The following is the code illustration for basic arithmetic in main.go:
package main
import "fmt"
func main() {
// declare variables
var a, b int
// assign values
a = 5
b = 10
// arithmetic operation
// addition
c := a + b
fmt.Printf("%d + %d = %d n",a,b,c)
// subtraction
d := a - b
fmt.Printf("%d - %d = %d n",a,b,d)
// division
e := float32(a) / float32(b)
fmt.Printf("%d / %d = %.2f n",a,b,e)
// multiplication
f := a * b
fmt.Printf("%d * %d = %d n",a,b,f)
}
Then, try to build and run it.
$ cd arithdemo
$ go build
$ go run main.go
The following is a sample output.
2.5 Mathematical Functions
Go provides math library which you can read it on https://golang.org/pkg/math/. For
illustration, we try to use several math functions.
Create a folder, called mathdemo. Then, create a file, called main.go. Write the following
code.
package main
import (
"fmt"
"math"
)
func main(){
a := 2.4
b := 1.6
c := math.Pow(a,2)
fmt.Printf("%.2f^%d = %.2f n",a,2,c)
c = math.Sin(a)
fmt.Printf("Sin(%.2f) = %.2f n",a,c)
c = math.Cos(b)
fmt.Printf("Cos(%.2f) = %.2f n",b,c)
c = math.Sqrt(a*b)
fmt.Printf("Sqrt(%.2f*%.2f) = %.2f n",a,b,c)
}
Then, try to build and run it.
$ cd mathdemo
$ go build
$ go run main.go
The following is a sample output.
2.6 Increment and Decrement
Go has special syntax for increment and decrement.
++ syntax for increment. a++ means a = a + 1
— syntay for decrement. a— means a = a - 1
For testing, create a folder, called incdec, and then create a file, called main.go. Write the
following script.
package main
import "fmt"
func main() {
// declare variables
var a = 4
// increment
fmt.Printf("a = %d n",a)
a = a + 1
fmt.Printf("a + 1 = %d n",a)
a++
fmt.Printf("a++ = %d n",a)
// decrement
a = a - 1
fmt.Printf("a - 1 = %d n",a)
a--
fmt.Printf("a-- = %d n",a)
}
Then, try to build and run it.
$ cd incdec
$ go build
$ go run main.go
The following is a sample output.
2.7 Getting Input from Keyboard
In fmt library, it provides a feature to get input from keyboard. We can use Scanf().
For illustration, we calculate circle area. In this case, we need an input for radius value.
Create a folder, called inputdemo. Then, create a file, called main.go, and write this script.
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Circle Area calculation")
fmt.Print("Enter a radius value: ")
var radius float64
fmt.Scanf("%f", &radius)
area := math.Pi * math.Pow(radius,2)
fmt.Printf("Circle area with radius %.2f = %.2f n",radius, area)
}
Then, try to build and run it.
$ cd inputdemo
$ go build
$ go run main.go
Entry an input for circle radius.
The following is a sample output.
2.8 Comparison Operators
You may determine equality or difference among variables or values. Here is the list of
comparison operatos:
== is equal to
!= is not equal
> is greater than
< is less than
>= is greater than or equal to
<= is less than or equal to
This is sample code for comparison usage.
package main
import "fmt"
func main() {
var (
a = 2
b = 10
)
fmt.Println(a>b)
fmt.Println(a<b)
fmt.Println(a>=b)
fmt.Println(a<=b)
fmt.Println(a!=b)
fmt.Println(a==b)
}
Build and run it.
A sample output of the program can be seen in Figure below.
2.9 Logical Operators
These operators can be used to determine the logic between variables or values.
&& and
|| or
! not
Sample code:
package main
import "fmt"
func main() {
var (
a = 5
b = 8
)
fmt.Println(a>b && a!=b)
fmt.Println(!(a>=b))
fmt.Println(a==b || a>b)
}
Build and run it.
A sample output of the program can be seen in Figure below.
2.10 Decision
There are two approaches to build decision on Go. We can use if..then and switch..case.
2.10.1 if..then
Syntax model for if..then can be formulated as below:
if conditional {
// do something
}else{
// do another job
}
conditional can be obtained by logical or/and comparison operations.
package main
import "fmt"
func main() {
var (
a = 5
b = 8
)
if a>b || a-b<a {
fmt.Println("conditional-->a>b || a-b<a")
}else{
fmt.Println("..another")
}
}
Build and run it.
A sample output of the program can be seen in Figure below.
2.10.2 switch..case
switch..case can be declared as below:
switch option {
case option1:
// do option1 job
case option2:
// do option2 job
}
Here is the sample code of switch..case usage:
package main
import "fmt"
func main() {
selected := 2
switch selected {
case 0:
fmt.Println("selected = 0")
case 1:
fmt.Println("selected = 1")
case 2:
fmt.Println("selected = 2")
case 3:
fmt.Println("selected = 3")
default:
fmt.Println("other..")
}
}
Build and run it.
A sample output of the program can be seen in Figure below.
2.11 Iteration - for
Iteration operation is useful when we do repetitive activities. The following is for syntax.
for initialization;conditional;increment/decrement {
}
For testing, write this script into a file, main.go.
package main
import "fmt"
func main() {
// iteration - for
var i int
for i=0;i<5;i++ {
fmt.Println(i)
}
for j:=5;j<11;j++ {
fmt.Println(j)
}
}
Build and run it.
A sample output of the program can be seen in Figure below.
2.12 Iteration - while
Go doesn’t provide while syntax like “C family” programming language. We can use for
which passes conditional value.
Write this script for testing.
package main
import "fmt"
func main() {
// iteration - while
// go doesn't provide while syntax. we can use for
i := 0
for i<5 {
fmt.Println(i)
i++
}
}
Build and run it.
A sample output of the program can be seen in Figure below.
2.13 break and continue
break can be used to stop on the code point. Otherwise, continue can be used to skip some
scripts. For illustration, we have a looping. The looping will be stopped using break if
value = 3. Another sample, we can skip the iteration with value = 7 using continue syntax.
Write this script.
package main
import "fmt"
func main() {
// iteration - for
var i int
for i=0;i<5;i++ {
if i==3 {
break
}
fmt.Println(i)
}
for j:=5;j<11;j++ {
if j==7 {
continue
}
fmt.Println(j)
}
}
Build and run it.
A sample output of the program can be seen in Figure below.
3. Arrays, Slices and Maps
This chapter explains how to work with Go collection.
3.1 Array
Go provides Array object for collection manipulation. We define our array variable as
follows.
var numbers[5] int
var cities[5] string
var matrix[3][3] int // array 2D
For illustration, we can build a new project, called arraydemo, by creating a folder, called
arraydemo.
$ mkdir arraydemo
$ cd arraydemo
Then, create a file, main.go. Import Go packages for our program.
package main
import (
"fmt"
"math/rand"
)
In this program, we can try to define several array variables. Set their values and display
them on Terminal.
func main() {
// define array
fmt.Println("define arrays")
var numbers[5] int
var cities[5] string
var matrix[3][3] int // array 2D
// insert data
fmt.Println(">>>>>insert array data")
for i:=0;i<5;i++ {
numbers[i] = i
cities[i] = fmt.Sprintf("City %d",i)
}
// insert matrix data
fmt.Println(">>>>>insert matrix data")
for i:=0;i<3;i++ {
for j:=0;j<3;j++ {
matrix[i][j] = rand.Intn(100)
}
}
// display data
fmt.Println(">>>>>display array data")
for j:=0;j<5;j++ {
fmt.Println(numbers[j])
fmt.Println(cities[j])
}
// display matrix data
fmt.Println(">>>>>display matrix data")
for i:=0;i<3;i++ {
for j:=0;j<3;j++ {
fmt.Println(matrix[i][j])
}
}
}
Save this code.
Build and run this program.
$ go build
$ go run main.go
You can see a sample of program output, shown in Figure below.
3.2 Slice
We can define an array without giving array length. Go uses Slice to do this case. To set
array length, we can use make() function.
For testing, we build a project, called slicedemo.
$ mkdir slicedemo
$ cd slicedemo
Then, create a file, main.go, and write this code.
package main
import (
"fmt"
"math/rand"
)
func main() {
// define slice
fmt.Println("define slices")
var numbers[] int
numbers = make([]int,5)
matrix := make([][]int,3*3)
// insert data
fmt.Println(">>>>>insert slice data")
for i:=0;i<5;i++ {
numbers[i] = rand.Intn(100) // random number
}
// insert matrix data
fmt.Println(">>>>>insert slice matrix data")
for i:=0;i<3;i++ {
matrix[i] = make([]int,3)
for j:=0;j<3;j++ {
matrix[i][j] = rand.Intn(100)
}
}
// display data
fmt.Println(">>>>>display sclice data")
for j:=0;j<5;j++ {
fmt.Println(numbers[j])
}
// display matrix data
fmt.Println(">>>>>display sclice 2D data")
for i:=0;i<3;i++ {
for j:=0;j<3;j++ {
fmt.Println(matrix[i][j])
}
}
}
Save this code.
Build and run this program.
$ go build
$ go run main.go
A sample of program output can be seen in Figure below.
3.3 Map
We can create an array with key-value. Go uses map() to implement key-value array.
For illustration, we create a project, called mapdemo.
$ mkdir mapdemo
$ cd mapdemo
We will define map variables. Then, set their values and dispay them on Terminal. Create
a file, called main.go. Write this code.
package main
import (
"fmt"
"math/rand"
)
func main() {
// define array
fmt.Println("define map")
products := make(map[string]int)
customers := make(map[string]int)
// insert data
fmt.Println(">>>>>insert map data")
products["product1"] = rand.Intn(100)
products["product2"] = rand.Intn(100)
customers["cust1"] = rand.Intn(100)
customers["cust2"] = rand.Intn(100)
// display data
fmt.Println(">>>>>display map data")
fmt.Println(products["product1"])
fmt.Println(products["product2"])
fmt.Println(customers["cust1"])
fmt.Println(customers["cust2"])
}
Save this code.
Build and run this program.
$ go build
$ go run main.go
A sample of program output can be seen in Figure below.
4. Functions
This chapter explains how to create function using Go.
4.1 Creating A Simple Function
Declaring function in Go has format as follows.
func function_name return_datatype {
return foo
}
For illustration, we can build a new project, called arraydemo, by creating a folder, called
arraydemo.
$ mkdir arraydemo
$ cd arraydemo
Create a file, main.go. Then, import Go package.
package main
import (
"fmt"
"math"
)
To create a simple function, you can write this code in main.go file.
func main(){
foo()
}
// a simple function
func foo() {
fmt.Println("foo() was called")
}
4.2 Function with Parameters
Sometimes you want to create a function with a parameter. You can implement it as
follows.
// a function with a parameter
func circle_area(r float64){
area := math.Pi * math.Pow(r,2)
fmt.Printf("Circle area (r=%.2f) = %.2f n",r, area)
}
If there are many parameters on function, we can define the function as below.
// a function with parameters
func calculate(a,b, c float64){
result := a*b*c
fmt.Printf("a=%.2f, b=%.2f, c=%.2f = %.2f n",a, b, c, result)
}
4.3 Function with Returning Value
You may want to create function that has a return value. Look this code for sample
illustration.
// a function with parameters and a return value
func advanced_calculate(a,b, c float64) float64 {
result := a*b*c
return result
}
4.4 Function with Multiple Returning Values
A function can return multiple returning values in Go. For instance, we return three values
in Go function. A sample code can be written as below.
// a function with parameters and multiple return values
func compute(a,b, c float64, name string) (float64,float64,string) {
result1 := a*b*c
result2 := a + b + c
result3 := result1 + result2
newName := fmt.Sprintf("%s value = %.2f", name,result3)
return result1, result2, newName
}
4.5 Function with Multiple Parameters and Returning Value
You may want to unlimited parameters on function. It possible to implement it in Go. We
can use … to define multiple parameters in a function.
// a function with zero or more parameters and a return value
func add(numbers ...int) int {
result := 0
for _, number := range numbers {
result += number
}
return result
}
4.6 Closure Function
We can define functions in a function. It’s called closure function. We can implement
closure function in Go as follows.
// a closure function
func closure_func(name string){
hoo := func(a,b int){
result := a*b
fmt.Printf("hoo() = %d n",result)
}
joo := func(a,b int) int {
return a*b + a
}
fmt.Printf("closure_func(%s) was calledn",name)
hoo(2,3)
val := joo(5,8)
fmt.Printf("val from joo() = %d n",val)
}
4.7 Recursion Function
Recursion function is a function where the solution to a problem depends on solutions to
smaller instances of the same problem (as opposed to iteration). For illustration, we can
implement Fibonacci problem using Go.
The following is a sample code for Fibonacci solution in Go.
// a recursion function
func fibonacci(n int) int {
if n==0{
return 0
}else if n==1 {
return 1
}
return (fibonacci(n-1) + fibonacci(n-2))
}
4.8 Testing
We can write code again from section 4.1 to 4.7 and use them in main entry. Write this
code on main.go file.
package main
import (
"fmt"
"math"
)
func main(){
foo()
circle_area(2.56)
calculate(2, 6.7, 5)
val := advanced_calculate(2, 4.8, 7)
fmt.Printf("advanced_calculate() = %.2f n",val)
val1,val2,val3 := compute(6, 2.7, 1.4, "energy")
fmt.Printf("val1=%.2f, val2=%.2f, val3="%s" n", val1, val2, val3)
result := add(1,2,3,4,5,6,7,8,9,10,11)
fmt.Printf("add() = %d n",result)
closure_func("testing")
ret := fibonacci(15)
fmt.Printf("fibonacci() = %d n",ret)
}
// a simple function
func foo() {
fmt.Println("foo() was called")
}
// a function with a parameter
func circle_area(r float64){
area := math.Pi * math.Pow(r,2)
fmt.Printf("Circle area (r=%.2f) = %.2f n",r, area)
}
// a function with parameters
func calculate(a,b, c float64){
result := a*b*c
fmt.Printf("a=%.2f, b=%.2f, c=%.2f = %.2f n",a, b, c, result)
}
// a function with parameters and a return value
func advanced_calculate(a,b, c float64) float64 {
result := a*b*c
return result
}
// a function with parameters and multiple return values
func compute(a,b, c float64, name string) (float64,float64,string) {
result1 := a*b*c
result2 := a + b + c
result3 := result1 + result2
newName := fmt.Sprintf("%s value = %.2f", name,result3)
return result1, result2, newName
}
// a function with zero or more parameters and a return value
func add(numbers ...int) int {
result := 0
for _, number := range numbers {
result += number
}
return result
}
// a closure function
func closure_func(name string){
hoo := func(a,b int){
result := a*b
fmt.Printf("hoo() = %d n",result)
}
joo := func(a,b int) int {
return a*b + a
}
fmt.Printf("closure_func(%s) was calledn",name)
hoo(2,3)
val := joo(5,8)
fmt.Printf("val from joo() = %d n",val)
}
// a recursion function
func fibonacci(n int) int {
if n==0{
return 0
}else if n==1 {
return 1
}
return (fibonacci(n-1) + fibonacci(n-2))
}
Save this code.
Build and run this program.
$ go build
$ go run main.go
A sample of program output can be seen in Figure below.
5. Pointers
This chapter we explore how to use Pointer in Go.
5.1 Pointer in Go
A pointer is a programming language object, whose value refers directly to (or “points to”)
another value stored elsewhere in the computer memory using its address, ref:
http://en.wikipedia.org/wiki/Pointer_(computer_programming) .
When we define x as int, we can x value by calling x = 1. To know the memory address of
x, we can use &x. To test, we build a new project. Create a folder, called pointers.
$ mkdir pointers
$ cd pointers
Creata a file, main.go, and write this code.
package main
import "fmt"
func main(){
var x int
x = 10
fmt.Println(x) // print a value of x
fmt.Println(&x) // print address of x
}
Save this file.
Try to build and run it.
$ go build
$ go run main.go
You can see x has a value 10 and its memory address 0xC082002238. Memory address
can be retrieved using & keyword.
In Go, we can define data type as Pointer using *, for instance var x *int. We can set
Pointer variable using *x = value. To set memory address on Pointer variable, we can use
x = memory_address.
For testing, we add the following code on main.go file.
package main
import "fmt"
func main(){
var x int
x = 10
fmt.Println(x) // print a value of x
fmt.Println(&x) // print address of x
// declare pointer
var num *int
val := new(int)
num = new(int)
*num = x // set value
val = &x // set address
fmt.Println("===pointer num===")
fmt.Println(*num) // print a value of x
fmt.Println(num) // print address of x
fmt.Println("===pointer val===")
fmt.Println(*val) // print a value of x
fmt.Println(val) // print address of x
}
Save this file.
Try to build and run it. A sample of program output is shown in Figure below.
5.2 Demo: Singly Linked List
In this section, we can create a singly linked list from scratch. You can read your Data
Structure book to understand what singly linked list is. You also read it on Wikipedia,
http://en.wikipedia.org/wiki/Linked_list#Singly_linked_lists .
Now we can create a singly linked list using Go. Firstly, we create folder, linkedlist.
$ mkdir linkedlist
$ cd linkedlist
Create a file, main.go. Import Go package and define struct for Pointer.
package main
import (
"fmt"
"math/rand"
)
type Node struct {
value int
next *Node
}
next is Pointer variable which refers to memory address of the next Pointer variable.
We create a function, add(), which we insert a new data on our singly linked list. The
following is implementation of add() function.
func add(list *Node,data int) *Node {
if list==nil {
list := new(Node)
list.value = data
list.next = nil
return list
}else{
temp := new(Node)
temp.value = data
temp.next = list
list = temp
return list
}
}
We also can display a content of singly linked list. Create a function, display(), and write
this code.
func display(list *Node){
var temp *Node
temp = list
for temp!=nil {
fmt.Println(temp.value)
temp = temp.next
}
}
In main entry, we define singly linked list as Pointer variable, called head. We add five
data into a Pointer list. Then, we display all data. Write the following code for main()
function.
func main(){
var head *Node
head = nil
// add 5 data
fmt.Println("=== insert 5 data=== ")
n := 0
for n < 5 {
fmt.Printf("data %dn",n)
head = add(head,rand.Intn(100))
n++
}
fmt.Println("=== display ===")
display(head)
}
Save this file.
Try to build and run it.
$ go build
$ go run main.go
A sample of program output can be seen in Figure below.
6. Structs and Methods
This chapter explains how to work with struct and method in Go.
6.1 Structs
We can extend our object using struct. If you have experience in C/C++, we use struct
approach in Go language.
To define a struct, we can use struct keyword, for instance, we define struct_name for
struct object.
type struct_name struct {
// fields
}
For illustration, we create a struct, Employee. Firstly, we build a new project by creating a
folder, called structdemo.
$ mkdir structdemo
$ cd structdemo
Then, create a file, called main.go. Firstly, we define our packages and a struct,
Employee.
package main
import (
"fmt"
"time"
)
// define a struct
type Employee struct {
id int
name string
country string
created time.Time
}
Employee struct has four fields such as id, name, country and created.
To use a struct in Go, we can instance our struct object using new(). Then, we set its
values.
Write this code in entry point on main.go file.
func main() {
// declare variable
var emp Employee
newEmp := new(Employee)
// set values
emp.id = 2
emp.name = "Employee 2"
emp.country = "DE"
emp.created = time.Now()
newEmp.id = 5
newEmp.name = "Employee 5"
newEmp.country = "UK"
newEmp.created = time.Now()
// display
fmt.Println("=====================")
fmt.Println(emp.id)
fmt.Println(emp.name)
fmt.Println(emp.country)
fmt.Println(emp.created)
fmt.Println("=====================")
fmt.Println(newEmp.id)
fmt.Println(newEmp.name)
fmt.Println(newEmp.country)
fmt.Println(newEmp.created)
}
Save this file.
Try to build and run it.
$ go build
$ go run main.go
A sample of program output:
6.2 Methods
We define methods in our struct object by passing struct object. For illustration, we create
Circle struct object which has the following methods:
display()
area()
circumference()
moveTo()
How to implement?
Create a folder, called structmethod.
$ mkdir structmethod
$ cd structmethod
The next step is to create a file, called main.go. Import our package and define Circle
struct object.
package main
import (
"fmt"
"math"
)
// define a struct
type Circle struct {
x,y int
r float64
}
Circle struct has three fields: x, y and r.
Basically, we can create struct method in the same way when you create a function. We
pass our struct object on the front of method name. The following is implementation our
struct methods.
func (c Circle) display() {
fmt.Printf("x=%d,y=%d,r=%.2fn",c.x,c.y,c.r)
}
func (c Circle) area() float64 {
return math.Pi * math.Pow(c.r,2)
}
func (c Circle) circumference() float64 {
return 2* math.Pi * c.r
}
func (c Circle) moveTo(newX,newY int) {
c.x = newX
c.y = newY
}
The last step is to use our struct method in main program. Write the following code.
func main() {
// methods
shape := Circle{10,5,2.8}
shape.display()
fmt.Printf("area=%2.fn",shape.area())
fmt.Printf("circumference=%2.fn",shape.circumference())
shape.moveTo(5,5)
shape.display()
}
Save this code.
Build and run main.go on your Terminal.
$ go build
$ go run main.go
A sample of program output:
7. String Operations
This chapter explains how to work with String operation in Go.
7.1 Getting Started
We already use string as data type. The following is a sample code to work with string
data and print it on Terminal.
// simple string demo
var str string
str = "Hello world"
fmt.Println(str)
In this section, we try to manipulate string data. We will explore several functions on
strconv, http://golang.org/pkg/strconv/ and strings,http://golang.org/pkg/strings/ packages.
Firstly, we build a new project by creating a folder, stringdemo.
$ mkdir stringdemo
$ cd stringdemo
Create a file, called main.go. Import fmt, strcov and strings packages.
package main
import (
"fmt"
"strconv"
"strings"
)
The next step is to explore how to work with string.
7.2 Concatenating Strings
If you have a list of string, you can concatenate into one string. You can use + operator
and fmt.Sprintf() function. Here is a sample code
str1 := "hello"
str2 := "world"
str3 := str1 + str2
fmt.Println(str3)
str4 := fmt.Sprintf("%s %s",str1,str2)
fmt.Println(str4)
7.3 String To Numeric
Sometime you want to do math operations but input data has string type. To convert string
type into numeric, you can use strcov.ParseInt() for String to Int and strcov.ParseFloat()
for string to Float.
The following is a sample code to implement string to numeric conversion.
fmt.Println("----demo String To Numeric----")
str_val1 := "5"
str_val2 := "2.8769"
var err error
var int_val1 int64
int_val1,err = strconv.ParseInt(str_val1,10,32) // base10, 64 size
if err==nil {
fmt.Println(int_val1)
}else{
fmt.Println(err)
}
var float_val2 float64
float_val2,err = strconv.ParseFloat(str_val2,64) // 64 size
if err==nil {
fmt.Println(float_val2)
}else{
fmt.Println(err)
}
7.4 Numeric to String
It is easy to convert numeric to String type, you can use fmt.Sprintf. You can get string
type automatically.
fmt.Println("----demo numeric to string----")
num1 := 8
num2 := 5.872
var str_num1 string
str_num1 = fmt.Sprintf("%d",num1)
fmt.Println(str_num1)
var str_num2 string
str_num2 = fmt.Sprintf("%f",num2)
fmt.Println(str_num2)
7.5 String Parser
The simple solution to parsing String uses Split() with delimiter parameter. For example,
you have String data with ; delimiter and want to parse it. Here is sample code
fmt.Println("----demo String Parser----")
data := "Berlin;Amsterdam;London;Tokyo"
fmt.Println(data)
cities := strings.Split(data, ";")
for _, city := range cities {
fmt.Println(city)
}
7.6 Check String Data Length
You can use len() to get the length of data.
fmt.Println("----demo String Length----")
str_data := "welcome to go"
len_data := len(str_data)
fmt.Printf("len=%d n",len_data)
7.7 Copy Data
You may copy some characters from String data. To do it, you can use [start:end] syntax.
Here is syntax format:
fmt.Println("----demo copy data----")
sample := "hello world, go!"
fmt.Println(sample)
fmt.Println(sample[0:len(sample)]) // copy all
fmt.Println(sample[:5]) // copy 5 characters
fmt.Println(sample[3:8]) // copy characters from index 3 until 8
fmt.Println(sample[len(sample)-5:len(sample)]) // 5 copy characters from t
7.8 Upper and Lower Case Characters
In some situation, you want to get all string data in upper or lower case characters. This
feature is built in String object. ToUpper() function is used to make whole string in upper
case and ToLower() is used to make whole string in lower case.
The following is a sample code to get upper and lower case characters.
fmt.Println("----demo upper/lower characters----")
message := "Hello World, GO!"
fmt.Println(message)
fmt.Println(strings.ToUpper(message)) // upper chars
fmt.Println(strings.ToLower(message)) // upper chars
7.9 Testing A Program
We can write our code in main.go completely as follows.
package main
import (
"fmt"
"strconv"
"strings"
)
func main(){
// simple string demo
var str string
str = "Hello world"
fmt.Println(str)
// Concatenating
str1 := "hello"
str2 := "world"
str3 := str1 + str2
fmt.Println(str3)
str4 := fmt.Sprintf("%s %s",str1,str2)
fmt.Println(str4)
// String To Numeric
fmt.Println("----demo String To Numeric----")
str_val1 := "5"
str_val2 := "2.8769"
var err error
var int_val1 int64
int_val1,err = strconv.ParseInt(str_val1,10,32) // base10, 64 size
if err==nil {
fmt.Println(int_val1)
}else{
fmt.Println(err)
}
var float_val2 float64
float_val2,err = strconv.ParseFloat(str_val2,64) // 64 size
if err==nil {
fmt.Println(float_val2)
}else{
fmt.Println(err)
}
// numeric to string
fmt.Println("----demo numeric to string----")
num1 := 8
num2 := 5.872
var str_num1 string
str_num1 = fmt.Sprintf("%d",num1)
fmt.Println(str_num1)
var str_num2 string
str_num2 = fmt.Sprintf("%f",num2)
fmt.Println(str_num2)
// String Parser
fmt.Println("----demo String Parser----")
data := "Berlin;Amsterdam;London;Tokyo"
fmt.Println(data)
cities := strings.Split(data, ";")
for _, city := range cities {
fmt.Println(city)
}
// String Data Length
fmt.Println("----demo String Length----")
str_data := "welcome to go"
len_data := len(str_data)
fmt.Printf("len=%d n",len_data)
// copy data
fmt.Println("----demo copy data----")
sample := "hello world, go!"
fmt.Println(sample)
fmt.Println(sample[0:len(sample)]) // copy all
fmt.Println(sample[:5]) // copy 5 characters
fmt.Println(sample[3:8]) // copy characters from index 3 until 8
fmt.Println(sample[len(sample)-5:len(sample)]) // 5 copy characters from t
// Upper and Lower Case Characters
fmt.Println("----demo upper/lower characters----")
message := "Hello World, GO!"
fmt.Println(message)
fmt.Println(strings.ToUpper(message)) // upper chars
fmt.Println(strings.ToLower(message)) // upper chars
}
Save this code.
Build and run main.go on your Terminal.
$ go build
$ go run main.go
A sample of program output:
8. File Operations
This chapter explains how to work with file operations.
8.1 Getting Started
We can work with I/O file using io package, http://golang.org/pkg/io/ .
For illustration, we can try to write and read text file. Firstly, we create a folder, called
fileio.
$ mkdir fileio
$ cd fileio
The next step is to build Go application to write and read a file.
8.2 Writing Data Into A File
To write and read a file, we can use io package. In this section, we try to write data into a
file.
Create a file, called main.go, and put it on <go_project_root>/fileio folder. Firstly, we
define our packages which we use.
import (
"fmt"
"io/ioutil"
)
Then, create a function, called writeFile(). Write this code.
func writeFile(message string) {
bytes := []byte(message)
ioutil.WriteFile("d:/temp/testgo.txt",bytes,0644)
fmt.Println("created a file")
}
You can see that we can create a file using ioutil.WriteFile(). We pass data in byte array
format. You can change file name and its path.
8.3 Reading Data From A File
To read data from a file, we create a function, called readFile(). Write this code.
func readFile(){
data, _ := ioutil.ReadFile("d:/temp/testgo.txt")
fmt.Println("file content:")
fmt.Println(string(data))
}
To read a content of file, we can use ioutil.ReadFile(). It return array of string.
Note: a file and its patch is similar to file on previous section.
8.4 Writing All
To simply, we can write our code in main.go file as follows.
package main
import (
"fmt"
"io/ioutil"
)
func main() {
// write data into a file
fmt.Println("writing data into a file")
writeFile("welcome to go")
readFile()
// read data from a file
fmt.Println("reading data from a file")
readFile()
}
func writeFile(message string) {
bytes := []byte(message)
ioutil.WriteFile("d:/temp/testgo.txt",bytes,0644)
fmt.Println("created a file")
}
func readFile(){
data, _ := ioutil.ReadFile("d:/temp/testgo.txt")
fmt.Println("file content:")
fmt.Println(string(data))
}
Save this file.
Now you can build and run it.
$ go build
$ go run main.go
A sample output of program is shown in Figure below.
9. Error Handling and Logging
This chapter explains how to handle errors and exceptions that occur in Go application.
9.1 Error Handling
Basically when we write a program and occur error on running, Go will catch program
error. It will generate a panic.
For illustration, we create a project by creating a folder, errorhandle.
$ mkdir errorhandle
$ cd errorhandle
Then, create a file, main.go, and write this code.
package main
import (
"fmt"
)
func main(){
calculate()
}
func calculate() {
fmt.Println("----demo error handling---")
a := 10
b := 0
c := 0
c = a/b
fmt.Printf("result = %.2f n",c)
fmt.Println("Done")
}
Now you can build and run it.
$ go build
$ go run main.go
This program output is shown in Figure below.
9.2 defer, panic(), and recover()
Go provide defer syntax to make sure our program run completely. panic() can be use to
raise error on our program.
For illustration, we add demoPanic() function on main.go from previous project. Then, we
call demoPanic() in main entry.
package main
import (
"fmt"
)
func main(){
demoPanic()
}
func demoPanic() {
fmt.Println("----demo error handling---")
defer func() {
fmt.Println("do something")
}()
panic("this is a panic from demoPanic()")
fmt.Println("This message will never show")
}
Now you can this program.
You can see function under defer run completely. When we call panic(), Go will raise error
on our program and then stopped this program.
Now how to catch error on Go program? we can use recover() to catch error.
Try to create calculaze2() function, and write this code.
package main
import (
"fmt"
)
func main(){
calculate2()
}
func calculate2() {
fmt.Println("----demo error handling---")
c := 0
defer func() {
a := 10
b := 0
c = a/b
if error := recover(); error != nil {
fmt.Println("Recovering….", error)
fmt.Println(error)
}
}()
fmt.Printf("result = %d n",c)
fmt.Println("Done")
}
Now you can run this program.
You can see the program occurred error but it can recover so the program can print
“result” and “Done” at the end of program.
9.3 try..catch
In this section, we explorer external library, Try/Catch/Finally, from
https://github.com/manucorporat/try . We can use try..catch to handle error in Go.
To install Go library from Github, you must instal git, http://git-scm.com/ . Download it
based on your platform. If you use Windows platform, don’t forget to set it on PATH on
Environment Variables.
The next step is to configure GOPATH. It represents our workspace path, for instance, my
workspace path is D:PE_PRESSeBookgo_progcodes. In Linux/Mac, you can define
your own workspace path in under your account home path, for instance. Further
information, you can read it on https://golang.org/doc/code.html .
If you use Linux/Mac, you can define GOPATH using export command or you add it on
your profile file.
$ mkdir $HOME/go
$ export GOPATH=$HOME/go
If you use Windows platform, you open Environment Variables. You can open it from
Advanced system settings. Then, click Environment Variables button. Add GOPATH
on your user and System variables.
For illustration, we create a project by creating a folder, trycatch.
$ mkdir trycatch
$ cd trycatch
Now we can install trycatch library from Github. Type the following command.
$ go get github.com/manucorporat/try
If you use Windows platform and get error related to libcurl.dll, you must copy libcurl.dll
from <installed_git_path>/bin folder to <installed_git_path>/libexec/git-core folder.
Now you can write a program. Create a file, called main.go, and write this code.
package main
import (
"fmt"
"github.com/manucorporat/try"
)
func main() {
try.This(func() {
a := 10
b := 0
c := 0
c = a/b
fmt.Printf("result = %.2f n",c)
}).Finally(func() {
fmt.Println("Done")
}).Catch(func(_ try.E) {
fmt.Println("exception catched") // print
try.Throw() // rethrow current exception!!
})
}
Save this code.
Now you can build and run this program.
$ go build
$ go run main.go
A program output can be seen in Figure below.
9.4 Logging
In previous section, we use fmt.Println() to print error message on console. Imagine there
are many messages on console and we want to identify which error message is. Go
package provides “log” to handle logging.
For illustration, we create a project by creating a folder, logging.
$ mkdir logging
$ cd logging
Then, try to create a file, main.go, and write this code.
package main
import (
"fmt"
"log"
"os"
)
func main() {
simpleLogging()
}
func simpleLogging(){
fmt.Println("-----------simple logging-----------")
log.Println("Hello World")
log.Println("This is a simple error")
}
Now you can build and run it.
$ go build
$ go run main.go
This program output is shown in Figure below.
We can modify our logging format by modifying log.Logger object. For illustration, create
a function, called formattingLogging(), and write this code.
func main() {
formattingLogging()
}
func formattingLogging(){
fmt.Println("-----------formattingLogging-----------")
var warning *log.Logger
warning = log.New(
os.Stdout,
"WARNING: ",
log.Ldate|log.Ltime|log.Lshortfile)
warning.Println("This is warning message 1")
warning.Println("This is warning message 2")
}
Now you can build and run this program. A sample output can be seen in Figure below.
We also can save our logging messages into a file. For instance, we save them on
myapp.log. Basically, we can open file using os.OpenFile(). Then, pass this object into
log.Logger object.
Try to create fileLogging() function and write this code.
func main() {
fileLogging()
}
func fileLogging(){
fmt.Println("-----------file logging-----------")
file, err := os.OpenFile("d:/temp/myapp.log",
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Println("Failed to open log file")
return
}
var logFile *log.Logger
logFile = log.New(
file,
"APP: ",
log.Ldate|log.Ltime|log.Lshortfile)
logFile.Println("This is error message 1")
logFile.Println("This is error message 2")
logFile.Println("This is error message 3")
fmt.Println("Done")
}
Note: You can change file path based on your platform.
Now you can build and run this program.
After that, you can open myapp.log file. You will see the logging message on this file.
10. Building Own Go Package
This chapter explains how to build own Go Package
10.1 Creating Simple Module
In this section, we create a simple module. We will call functions from external file (*.go)
in the same package, main package.
Firstly, create new project, called mymodule.
$ mkdir mymodule
$ cd mymodule
Then, create a file, called simplemath.go. We define three functions. Write the following
code.
package main
func Add(a,b int) int {
return a+b
}
func Subtract(a,b int) int {
return a-b
}
func Multiply(a,b int) int {
return a*b
}
Note: Method name is written in Pascalcase, for instance HelloWorld(), DoProcessing(),
IsEmpty().
Now we will call three function (simplemath.go) from main entry. Create a new file,
called main.go, and write this code.
package main
import (
"fmt"
)
func main(){
fmt.Println("access mymodule…")
var c int
c = Add(10,6)
fmt.Printf("add()=%dn",c)
c = Subtract(5,8)
fmt.Printf("subtract()=%dn",c)
c = Multiply(5,3)
fmt.Printf("multiply()=%dn",c)
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go simplemath.go
A sample output can be seen in Figure below.
10.2 Building Own Package
In previous program, we create a module in main package. We create a package and then
use it in our program.
The first thing we should do is to configure GOPATH. It represents our workspace path,
for instance, my workspace path is D:PE_PRESSeBookgo_progcodes. In Linux/Mac,
you can define your own workspace path in under your account home path, for instance.
Further information, you can read it on https://golang.org/doc/code.html .
If you use Linux/Mac, you can define GOPATH using export command or you add it on
your profile file.
$ mkdir $HOME/go
$ export GOPATH=$HOME/go
If you use Windows platform, you open Environment Variables. You can open it from
Advanced system settings. Then, click Environment Variables button. Add GOPATH
on your user and System variables.
In this section, we organize our workspace as follows:
–- $GOPATH
––-src
–––-simplemodule
–––-simplemoduletest
For instance, we already been on GOPATH. Then, create src/simplemodule and
src/simplemoduletest folders.
$ mkdir src
$ cd src
$ mkdir simplemodule
$ mkdir simplemoduletest
A sample illustration for our lab path is shown in Figure below.
Now you can create a file, called simplemath.go on simplemath folder. Write the
following code.
package simplemath
func Add(a,b int) int {
return a+b
}
func Subtract(a,b int) int {
return a-b
}
func Multiply(a,b int) int {
return a*b
}
Note: Method name is written in Pascalcase, for instance HelloWorld(), DoProcessing(),
IsEmpty().
To compile our package, you can navigate to simplemodule directory, then call go build
and install.
$ cd simplemodule
$ go build
$ go install
If success, it will create a folder, called pkg. You can see your compiled package file, for
instance, simplemodule.a
The next step is to use simplemodule package.
Create a file, called main.go on simplemathtest folder.
package main
import (
"fmt"
"simplemodule"
)
func main(){
fmt.Println("access mymodule…")
var c int
c = simplemath.Add(5,8)
fmt.Printf("add()=%dn",c)
c = simplemath.Subtract(5,8)
fmt.Printf("subtract()=%dn",c)
c = simplemath.Multiply(5,3)
fmt.Printf("multiply()=%dn",c)
}
Save all. Now you can compile and run this program.
$ cd simplemathtest
$ go build
$ go run main.go
You can see the sample output can be seen in Figure below.
11. Concurrency
This chapter explains how to create concurrency in Go
11.1 Getting Started
We can run a program or a function in background using Go. In this chapter, we explore
several scenarios to build concurrency application.
11.2 Goroutines
Basically, we can define our Go background using go..<program code>.
For illustration, create new project, called goroutines.
$ mkdir goroutines
$ cd goroutines
Create a file, maing.go, and write this code.
package main
import (
"fmt"
"time"
)
func main(){
fmt.Printf("goroutines demon")
// run func in background
go calculate()
index := 0
// run in background
go func() {
for index < 6 {
fmt.Printf("go func() index= %d n", index)
var result float64 = 2.5 * float64(index)
fmt.Printf("go func() result= %.2f n", result)
time.Sleep(500 * time.Millisecond)
index++
}
}()
// run in background
go fmt.Printf("go printed in the backgroundn")
// press ENTER to exit
var input string
fmt.Scanln(&input)
fmt.Println("done")
}
func calculate() {
i := 12
for i < 15 {
fmt.Printf("calculate()= %d n", i)
var result float64 = 8.2 * float64(i)
fmt.Printf("calculate() result= %.2f n", result)
time.Sleep(500 * time.Millisecond)
i++
}
}
In this code, we try to run program in background for functions and lines of code. We use
go statement to represent background process.
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
A sample output can be seen in Figure below.
You can see the program is running randomly due to all codes run on background
(concurrency).
11.3 Synchronizing Goroutines
We can synchronize among background codes in Go. One of the solution is to use sync
library. In this section, we use sync.Mutex.Lock and sync.Mutex.Unlock for
synchronization.
For illustration, create new project, called syncgoroutines.
$ mkdir syncgoroutines
$ cd syncgoroutines
Create a file, main.go, and write this code.
package main
import (
"fmt"
"sync"
"math/rand"
"time"
)
type Task struct {
value int
executedBy string
}
var total int
var task Task
var lock sync.Mutex
func main(){
fmt.Printf("synchronizing goroutines demon")
total = 0
task.value = 0
task.executedBy = ""
display()
// run background
go calculate()
go perform()
// press ENTER to exit
var input string
fmt.Scanln(&input)
fmt.Println("done")
}
func calculate(){
for total < 10 {
lock.Lock()
task.value = rand.Intn(100)
task.executedBy = "from calculate()"
display()
total++
lock.Unlock()
time.Sleep(500 * time.Millisecond)
}
}
func perform(){
for total < 10 {
lock.Lock()
task.value = rand.Intn(100)
task.executedBy = "from perform()"
display()
total++
lock.Unlock()
time.Sleep(500 * time.Millisecond)
}
}
func display(){
fmt.Println("--------------------------")
fmt.Println(task.value)
fmt.Println(task.executedBy)
fmt.Println("--------------------------")
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
A sample output can be seen in Figure below.
11.4 Channels
We can create channels in Go and then we can communicate among Goroutines using
these channel. For illustration, we create a channel which hold number data. To insert data
in channel, we can use channel <-. Otherwise, we can get data from a channel using <-
channel.
For testing, create new project, called simplechannel.
$ mkdir simplechannel
$ cd simplechannel
Create a file, main.go, and write this code.
package main
import (
"fmt"
)
func main(){
fmt.Println("simple channel")
// define a channel
c := make(chan int)
// run a function in background
go func() {
fmt.Println("goroutine process")
c <- 10 // write data to a channel
}()
val := <-c // read data from a channel
fmt.Printf("value: %dn",val)
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
A sample output can be seen in Figure below.
12. Encoding
This chapter explains how to work with encoding in Go
12.1 Getting Started
In this chapter, we explore encoding package, http://golang.org/pkg/encoding/ . The
following is a list of our demo to illustrate how to use encoding package:
Base64
Hexadecimal
JSON
XML
CSV
For testing, you can create a new project, called encoding.
$ mkdir encoding
$ cd encoding
Create a file, main.go. Firstly, we import our Go packages for the demo. Write this code.
package main
import (
"fmt"
"encoding/base64"
"encoding/hex"
"encoding/json"
"encoding/xml"
"encoding/csv"
"os"
)
12.2 Encoding Base64
The first demo is to work with base64 encoding. We can use base64
package, http://golang.org/pkg/encoding/base64/ . To encode string to base64 string, we
can use EncodeToString(). Otherwise, we can decode it using DecodeString() function.
For testing, we encode a string message to base64. Then, we decode base64 message to
original message. Create a function, called demoBase64(). Call this function to main entry.
func main(){
message := "hello,go (*w3hu%#"
demoBase64(message)
}
func demoBase64(message string) {
fmt.Println("--------Demo encoding base64--------")
fmt.Println("plaintext:")
fmt.Println(message)
encoding := base64.StdEncoding.EncodeToString([]byte(message))
fmt.Println("base64 msg:")
fmt.Println(encoding)
decoding, _ := base64.StdEncoding.DecodeString(encoding)
fmt.Println("decoding base64 msg:")
fmt.Println(string(decoding))
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
A sample output can be seen in Figure below.
12.3 Hexadecimal
The second demo is to encode and decode string to Hexademical. We can use hex
package, http://golang.org/pkg/encoding/hex/, to implement our demo.
Create a function, called demoHex(). The following is implementation of
encoding/decoding Hexadecimal.
func main(){
message := "hello,go (*w3hu%#"
demoHex(message)
}
func demoHex(message string) {
fmt.Println("--------Demo encoding Hex--------")
fmt.Println("plaintext:")
fmt.Println(message)
encoding := hex.EncodeToString([]byte(message))
fmt.Println("Hex msg:")
fmt.Println(encoding)
decoding, _ := hex.DecodeString(encoding)
fmt.Println("decoding Hex msg:")
fmt.Println(string(decoding))
}
Save this code. Now you can build and run this program.
A sample output can be seen in Figure below.
12.4 JSON
The third demo is to construct and parse JSON data. In Go, we can use json
package, http://golang.org/pkg/encoding/json/ . In this demo, we try to convert struct data
to JSON data. Then, we can convert JSOn string to struct.
Now you can create a function, called demoJson(), and write this code.
func main(){
demoJson()
}
func demoJson(){
fmt.Println("--------Demo encoding json--------")
type Employee struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
// struct to json
fmt.Println(">>>>struct to json….")
emp := &Employee{Id:"12345",Name:"Michael",Email:"michael@email.com"
b, err := json.Marshal(emp)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(b))
// json string to struct
fmt.Println(">>>>json to struct….")
var newEmp Employee
str := `{"Id":"4566","Name":"Brown","Email":"brown@email.com"}`
json.Unmarshal([]byte(str),&newEmp)
fmt.Printf("Id: %sn",newEmp.Id)
fmt.Printf("Name: %sn",newEmp.Name)
fmt.Printf("Email: %sn",newEmp.Email)
}
Save this code. Now you can build and run this program.
A sample output can be seen in Figure below.
12.5 XML
The fourth demo is to read and write XML data. We xml
package, http://golang.org/pkg/encoding/xml/ . In this demo, we construct XML from a
struct which has nested struct. In XML data nested struct can be converted to XML
attribute and value.
Now you can create a function, called demoXml(), and write this code.
func main(){
demoXml()
}
func demoXml(){
fmt.Println("--------Demo encoding xml--------")
type EmployeeCountry struct {
CountryCode string `xml:"code,attr"` // XML attribute: code
CountryName string `xml:",chardata"` // XML value
}
type Employee struct {
XMLName xml.Name `xml:"employee"`
Id string `xml:"id"`
Name string `xml:"name"`
Email string `xml:"email"`
Country EmployeeCountry `xml:"country"`
}
// struct to xml
fmt.Println(">>>>struct to xml….")
emp := &Employee{Id:"12345",Name:"Michael",Email:"michael@email.com"
Country: EmployeeCountry{CountryCode:"DE",CountryName:
b, err := xml.Marshal(emp)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(b))
// xml string to struct
fmt.Println(">>>>xml to struct….")
var newEmp Employee
str := `<employee><id>555</id><name>Lee</name><email>lee@email.com</email>
xml.Unmarshal([]byte(str),&newEmp)
fmt.Printf("Id: %sn",newEmp.Id)
fmt.Printf("Name: %sn",newEmp.Name)
fmt.Printf("Email: %sn",newEmp.Email)
fmt.Printf("CountryCode: %sn",newEmp.Country.CountryCode)
fmt.Printf("CountryName: %sn",newEmp.Country.CountryName)
}
Save this code. Now you can build and run this program.
A sample output can be seen in Figure below.
12.6 CSV
The last demo is to read and write data CSV which is a collection of comma-separated
data. We can access CSV file using csv package, http://golang.org/pkg/encoding/csv/ .
For testing, we have a CSV file, demo.csv, with the following content.
Employee 1;employee1@email.com;DE
Employee 2;employee2@email.com;UK
Employee 3;employee3@email.com;UK
Employee 4;employee4@email.com;NL
Employee 5;employee5@email.com;US
Employee 6;employee6@email.com;JP
Employee 7;employee7@email.com;DE
Create a function, demoCsv(). This function will read CSV file, demo.csv, and convert
these data to array of struct. After that, we write array of struct to a new CSV file, called
employee.csv.
The following is implementation of reading/writing CSV file.
func main(){
demoCsv()
}
func demoCsv(){
fmt.Println("--------Demo encoding csv--------")
type Employee struct {
Name string
Email string
Country string
}
// read csv file to a array of struct
fmt.Println(">>>>read a csv file and load to array of struct….")
file, err := os.Open("D:/PE_PRESS/eBook/go_prog/codes/src/encoding/demo.cs
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
reader := csv.NewReader(file)
reader.FieldsPerRecord = 3
reader.Comma = ';'
csvData, err := reader.ReadAll()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
var emp Employee
var employees []Employee
for _, item := range csvData {
emp.Name = item[0]
emp.Email = item[1]
emp.Country = item[2]
employees = append(employees, emp)
fmt.Printf("name: %s email: %s country: %sn", item[0], item[1],item[
}
fmt.Println(">>>>show all employee structs….")
fmt.Println(employees)
// write data to csv file
fmt.Println(">>>>write data to a csv file….")
csvFile, err := os.Create("D:/PE_PRESS/eBook/go_prog/codes/src/encoding/em
if err != nil {
fmt.Println("Error:", err)
return
}
defer csvFile.Close()
writer := csv.NewWriter(csvFile)
writer.Comma = ';'
for _, itemEmp := range employees {
records := []string{itemEmp.Name,itemEmp.Email,itemEmp.Country}
err := writer.Write(records)
if err != nil {
fmt.Println("Error:", err)
return
}
}
writer.Flush()
fmt.Println(">>>>Done")
}
Note: You can change CSV file path.
Save this code. Now you can build and run this program.
A sample output can be seen in Figure below.
If you open employee.csv, you get a content of employee data like a content of demo.csv
file.
13. Hashing and Cryptography
This chapter explains how to work with hashing and cryptography in Go
13.1 Getting Started
Hashing is generating a value or values from a string of text using a mathematical
function. Cryptography is the practice and study of techniques for secure communication
in the presence of third parties (called adversaries),
http://en.wikipedia.org/wiki/Cryptography . In this chapter, I don’t explain mathematical
hashing and Cryptography. You can read those materials on textbooks.
In this chapter, we explore how to work with hashing implementation using Go. The
following is hashing algorithms which we use in this book:
MD5
SHA256
Hashing with Key (HMAC)
The next topic is to implement Cryptography using Go. We explore symmetric and
asymmetric Cryptography.
Firstly, we can create a new project, called cryptodemo.
$ mkdir cryptodemo
$ cd cryptodemo
Create a file, main.go. Firstly, we import our Go packages for the demo. Write this code.
package main
import (
"fmt"
"crypto/md5"
"crypto/sha256"
"crypto/hmac"
"crypto/aes"
"crypto/rsa"
"crypto/cipher"
"crypto/rand"
"crypto/x509"
"encoding/hex"
"encoding/base64"
"encoding/pem"
"io"
"io/ioutil"
)
Let’s start to explore hashing and cryptography using Go.
13.2 Hashing
Basically, you can explore how to implement hashing or hash function using Go
via http://golang.org/pkg/crypto/ . In this section, we explore several hashing algorithms,
for instance, MD5, SHA256 and HMAC.
13.2.1 Hashing with MD5
We can use MD5 using md5 package, http://golang.org/pkg/crypto/md5/ . To calculate a
hash value from a text , we can call Sum() function.
For illustration, we create a function, demoHash_md5(), and write this code.
func demoHash_md5() {
fmt.Println("--------Demo encoding hash using md5--------")
message := "Hello world, go!"
fmt.Println("plaintext:")
fmt.Println(message)
h := md5.New()
h.Write([]byte(message))
hash_message := hex.EncodeToString(h.Sum(nil))
fmt.Println("hashing message:")
fmt.Println(hash_message)
}
13.2.2 Hashing with SHA256
The second demo is to implement hash function using SHA256. Go provides sha256
package, http://golang.org/pkg/crypto/sha256/, to implement hash function using SHA256.
For illustration, we create a function, demoHash_sha256(), and write this code.
func demoHash_sha256() {
fmt.Println("--------Demo encoding hash using sha256--------")
message := "Hello world, go!"
fmt.Println("plaintext:")
fmt.Println(message)
h := sha256.New()
h.Write([]byte(message))
hash_message := hex.EncodeToString(h.Sum(nil))
fmt.Println("hashing message:")
fmt.Println(hash_message)
}
13.2.3 Hashing with Key Using HMAC
A keyed-hash message authentication code (HMAC) is a specific construction for
calculating a message authentication code (MAC) involving a cryptographic hash function
in combination with a secret cryptographic key, http://en.wikipedia.org/wiki/Hash-
based_message_authentication_code . In Go, we can hmac
package, http://golang.org/pkg/crypto/hmac/ , to implement HMAC algorithm.
For illustration, we create a function, demoHashKey(), and write this code.
func demoHashKey(key,message string) {
fmt.Println("--------Demo encoding hash with key: HMAC and sha256--------"
fmt.Println("key:")
fmt.Println(key)
fmt.Println("plaintext:")
fmt.Println(message)
hmacKey := []byte(key)
h := hmac.New(sha256.New, hmacKey)
h.Write([]byte(message))
hash_message := hex.EncodeToString(h.Sum(nil))
fmt.Println("hashing message:")
fmt.Println(hash_message)
}
13.2.4 Testing
Save all code for our demo on section 13.2.1, 13.2.2 and 13.2.3. To testing, we call these
functions in main entry. Write this code.
func main(){
demoHash_md5()
demoHash_sha256()
demoHashKey("mykey","Hello world, go!")
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
A sample output can be seen in Figure below.
13.3 Cryptography
In this section, we focus Symmetric and Asymmetric Cryptography. In Symmetric
Cryptography, we use the same key to encrypt and decrypt. Otherwise, Asymmetric
Cryptography uses different key to encrypt and decrypt.
We explore these on the next section.
13.3.1 Symmetric Cryptography
There are many algorithms to implement Symmetric Cryptography. In this section, we use
AES algorithm. The Advanced Encryption Standard (AES) is a specification for the
encryption of electronic data established by the U.S. National Institute of Standards and
Technology (NIST) in
2001, http://en.wikipedia.org/wiki/Advanced_Encryption_Standard.
For illustration, we create two functions, encrypt_symmetric_crpyto() and
decrypt_symmetric_crpyto(). The following is implementation of
encrypt_symmetric_crpyto().
func encrypt_symmetric_crpyto(key,message string) string {
fmt.Println("--------Demo encrypt encrypt_symmetric_crpyto--------")
if len(key)!=16 && len(key)!=24 && len(key)!=32 {
fmt.Println("key must 16,24,32 byte length")
return ""
}
bc, err := aes.NewCipher([]byte(key))
if err != nil {
panic(err)
}
text := []byte(message)
ciphertext := make([]byte, aes.BlockSize+len(text))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
cfb := cipher.NewCFBEncrypter(bc, iv)
cfb.XORKeyStream(ciphertext[aes.BlockSize:], text)
return base64.StdEncoding.EncodeToString(ciphertext)
}
Explanation:
Define a key. It should be 16, 24, or 32 key length
Instantiate AES using NewCipher() with passing key value
Calculate IV value
Encrypt message in array of byte format by calling NewCFBEncrypter()
The result is be encoded to base64 string
The following is implementation of encrypt_symmetric_crpyto().
func decrypt_symmetric_crpyto(key,message string) string {
fmt.Println("--------Demo decrypt decrypt_symmetric_crpyto--------")
if len(key)!=16 && len(key)!=24 && len(key)!=32 {
fmt.Println("key must 16,24,32 byte length")
return ""
}
encrypted,_ := base64.StdEncoding.DecodeString(message)
bc, err := aes.NewCipher([]byte(key))
if err != nil {
panic(err)
}
if len(encrypted) < aes.BlockSize {
panic("ciphertext too short")
}
iv := encrypted[:aes.BlockSize]
encrypted = encrypted[aes.BlockSize:]
cfb := cipher.NewCFBDecrypter(bc, iv)
cfb.XORKeyStream(encrypted, encrypted)
return string(encrypted)
}
Explanation:
Define a key. It should be 16, 24, or 32 key length
Instantiate AES using NewCipher() with passing key value
Calculate IV value
Encrypt message in array of byte format by calling NewCFBDecrypter()
The result is be encoded to string
Now we can call these functions in main entry. Write this code.
func main(){
// symmetric crypto
key := "this is key 1234"
message := "Hello world, go!"
encrypted := encrypt_symmetric_crpyto(key,message)
fmt.Println("message:")
fmt.Println(message)
fmt.Println("key:")
fmt.Println(key)
fmt.Println("encrypted:")
fmt.Println(encrypted)
decrypted := decrypt_symmetric_crpyto(key,encrypted)
fmt.Println("encrypted message:")
fmt.Println(encrypted)
fmt.Println("key:")
fmt.Println(key)
fmt.Println("decrypted:")
fmt.Println(decrypted)
}
Now you can build and run it. A sample output can be seen in Figure below.
13.3.2 Asymmetric Cryptography
The common algorithm to implement Asymmetric Cryptography is RSA which is widely
used for secure data transmission. You read a brief description in
Wikipedia, http://en.wikipedia.org/wiki/RSA_(cryptosystem) .
Go has library for RSA implementation. In this section, we try to implement RSA using
Go. The following is our scenario:
Generate RSA keys (public and private keys)
Save these keys to two files (public and private key files)
For encryption, we use public key file
For decryption, we use private key file
We store public and private keys into a file in PEM data encoding. We can use pem
package from Go, http://golang.org/pkg/encoding/pem/ .
To generate public and private keys for RSA, we create a function, generateRSAkeys().
After generated keys, we save these keys to files. The following is implementation for
generating keys.
func generateRSAkeys(){
fmt.Println("Generating RSA keys….")
// change files and their paths
privKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/private.rsa
pubKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/public.rsa.k
// generate RSA keys
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
// extract private and public keys from RSA keys
privASN1 := x509.MarshalPKCS1PrivateKey(privateKey)
pubASN1, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
if err != nil {
panic(err)
}
// store private and public keys into files
privBytes := pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privASN1,
})
pubBytes := pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubASN1,
})
ioutil.WriteFile(privKeyFile, privBytes, 0644)
ioutil.WriteFile(pubKeyFile, pubBytes, 0644)
fmt.Println("Done")
}
This code will generate two files, private.rsa.key and public.rsa.key files.
To encrypt data, we create a function, encrypt_asymmetric_crypto(). Firstly, we load
public key. Then, encrypt the message using RSA. The following is code implementation
for encrypt_asymmetric_crypto() function.
func encrypt_asymmetric_crypto(message string) string {
fmt.Println("--------Demo encrypt encrypt_asymmetric_crypto--------"
// public key file
pubKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/public.rsa.k
// read public key from file
pubBytes, err := ioutil.ReadFile(pubKeyFile)
if err != nil {
panic(err)
}
pubBlock, _ := pem.Decode(pubBytes)
if pubBlock == nil {
fmt.Println("Failed to load public key file")
return ""
}
// Decode the RSA public key
publicKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes)
if err != nil {
fmt.Printf("bad public key: %s", err)
return ""
}
// encrypt message
msg := []byte(message)
encryptedmsg, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.Publ
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(encryptedmsg)
}
To decrypt data, we create a function, decrypt_asymmetric_crypto(). Firstly, we load
private key. Then, decrypt the message using RSA. The following is code implementation
for decrypt_asymmetric_crypto() function.
func decrypt_asymmetric_crypto(message string) string {
fmt.Println("--------Demo decrypt decrypt_asymmetric_crypto--------"
// private key file
privKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/private.rsa
// read private key from file
privBytes, err := ioutil.ReadFile(privKeyFile)
if err != nil {
panic(err)
}
privBlock, _ := pem.Decode(privBytes)
if privBlock == nil {
fmt.Println("Failed to load private key file")
return ""
}
// Decode the RSA private key
privateKey, err := x509.ParsePKCS1PrivateKey(privBlock.Bytes)
if err != nil {
fmt.Printf("bad public key: %s", err)
return ""
}
// encrypt message
encrypted,_ := base64.StdEncoding.DecodeString(message)
decrypteddmsg, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encrypt
if err != nil {
panic(err)
}
return string(decrypteddmsg)
}
Save all. Now you can implement our functions to main entry. Write this code.
func main(){
// asymmetric crypto
generateRSAkeys()
plainText := "Hello world, go!"
fmt.Println("plainText:")
fmt.Println(plainText)
rsa_encrypted := encrypt_asymmetric_crypto(plainText)
fmt.Println("encrypted:")
fmt.Println(rsa_encrypted)
rsa_decrypted := decrypt_asymmetric_crypto(rsa_encrypted)
fmt.Println("decrypted:")
fmt.Println(rsa_decrypted)
}
Now you can build and run it. A sample output can be seen in Figure below.
You can open public.rsa.key to see our RSA public key value.
You can also open private.rsa.key to see our RSA private key value.
14. Database Programming
This chapter explains how to build database application using Go.
14.1 Database for Go
Go can communicate with database server through database driver. Go provides generic
interfaces for database drive on http://golang.org/pkg/database/ . We must install database
driver and Go database package before we start to develop database application.
In this chapter, I only focus on MySQL scenario.
14.2 MySQL Driver for Go
We use Go-MySQL-Driver for database driver. Further information about this driver,
please visit on https://github.com/go-sql-driver/mysql .
To install Go-MySQL-Driver, you can try to write this command in terminal
$ go get github.com/go-sql-driver/mysql
After finished, we can do testing.
14.3 Testing Connection
In this section, we try to connect MySQL database. Firstly, we can create a new project,
called mysqldemo.
$ mkdir mysqldemo
$ cd mysqldemo
Create a file, main.go. Firstly, we import our Go packages for the demo. Write this code.
package main
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
Firstly, we can start to create simple Go application to connect to mysql database. Write
this code
func main(){
testConnection()
}
func testConnection(){
// change database user and password
db, err := sql.Open("mysql",string("user:password@tcp(127.0.0.1:3306)/rese
if err != nil {
panic(err)
}
err = db.Ping() // test connection
if err != nil {
panic(err.Error())
}
fmt.Println("connected")
defer db.Close()
}
change host, user, and password based on your mysql database configuration and
authentication.
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
A sample output can be seen in Figure below.
14.4 Querying
In this section, we try to insert data into a table. The following is our table scheme on
MySQL.
Here is sample code to insert data into mysql database using Go.
func main(){
insertData()
}
func insertData(){
db, err := sql.Open("mysql",string("researcher:researcher@tcp(127.0.0.1:33
if err != nil {
panic(err)
}
err = db.Ping() // test connection
if err != nil {
panic(err.Error())
}
fmt.Println("connected")
// prepare development
stmt, err := db.Prepare("INSERT INTO sensordevice(deviceid,temperature,hum
if err != nil {
panic(err)
}
defer stmt.Close()
fmt.Println("inserting data…")
for i := 0; i < 10; i++ {
_, err = stmt.Exec(2,0.2*float64(i),0.6*float64(i),0.5*float64(i),
if err != nil {
panic(err)
}
}
fmt.Println("done")
defer db.Close()
}
After finished, we can do testing.
You can verify this data into your table.
15. Socket Programming
This chapter explains how to create socket application using Go.
15.1 Socket Module
We can create application based on socket stack using net package. You can find it for
further information on http://golang.org/pkg/net/. I recommend you to read some books or
websites about the concept of socket.
15.2 Hello World
To get started, we create a simple application to get a list of IP Address in local computer.
We can use net package and call Interfaces() to get a list of network interfaces in our local
computer. Each network interface provides information about IP address.
In this section, we try to get local IP Address. Firstly, we can create a new project, called
netdemo.
$ mkdir netdemo
$ cd netdemo
Create a file, main.go. Then, write this code.
package main
import (
"fmt"
"net"
)
func main(){
ifaces, err := net.Interfaces()
if err!=nil {
panic(err)
}
fmt.Println("getting local IP Address…")
for _, i := range ifaces {
addrs, err := i.Addrs()
if err!=nil {
panic(err)
}
for _, addr := range addrs {
switch v := addr.(type) {
case *net.IPAddr:
if v.String()!="0.0.0.0"{
fmt.Println(v.String())
}
}
}
}
}
Save this code. Try to build and run it.
The following is a sample program output which runs on Windows:
15.3 Client/Server Socket
Now we create a client/server socket using Go. We will use net package to build
client/server application. For illustration, we create server and client.
15.3.1 Server Socket
How to create server socket? It is easy. The following is a simple algorithm how to build
server socket
create server socket
listen incoming client on the specific port
if client connected, listen incoming data and then disconnect from client
In this section, we build server app. Firstly, we can create a new project, called netserver.
$ mkdir netserver
$ cd netserver
Create a file, main.go. Write this code.
package main
import (
"fmt"
"net"
"os"
)
const (
SVR_HOST = "localhost"
SVR_PORT = "9982"
SVR_TYPE = "tcp"
)
func main() {
fmt.Println("server is running")
svr, err := net.Listen(SVR_TYPE, SVR_HOST+":"+SVR_PORT)
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
defer svr.Close()
fmt.Println("Listening on " + SVR_HOST + ":" + SVR_PORT)
fmt.Println("Waiting client…")
for {
conn, err := svr.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
fmt.Println("client connected")
go handleClient(conn)
}
}
func handleClient(conn net.Conn) {
buff := make([]byte, 1024)
msgLen, err := conn.Read(buff)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
fmt.Println("Received: ",string(buff[:msgLen]))
conn.Close()
}
It uses port 9982. You can change it.
15.3.2 Client Socket
Client socket is client application that connects to server and then sends/receives data
from/to server. We should know about IP address and port from target server. We can call
Dial() to connect to server. Use Write() for sending data.
In this section, we build client app. Firstly, we can create a new project, called netclient.
$ mkdir netclient
$ cd netclient
Create a file, main.go. Write this code.
package main
import (
"fmt"
"net"
)
const (
SVR_HOST = "localhost"
SVR_PORT = "9982"
SVR_TYPE = "tcp"
)
func main() {
fmt.Println("client is running")
conn, err := net.Dial(SVR_TYPE, SVR_HOST+":"+SVR_PORT)
if err != nil {
panic(err)
}
fmt.Println("send data")
_, err = conn.Write([]byte("message from client"))
defer conn.Close()
}
15.3.3 Testing
Now we can test our client/server application. Firstly, we run server application and then
execute client application.
Here is sample of program output for server application:
Here is sample of program output for client application:
Source Code
You can download source code on http://www.aguskurniawan.net/book/go_cd.zip .
Contact
If you have question related to this book, please contact me at aguskur@hotmail.com . My
blog: http://blog.aguskurniawan.net

More Related Content

Similar to Go Programming by Example_ Nho Vĩnh Share.pdf

Fullstack Academy - Awesome Web Dev Tips & Tricks
Fullstack Academy - Awesome Web Dev Tips & TricksFullstack Academy - Awesome Web Dev Tips & Tricks
Fullstack Academy - Awesome Web Dev Tips & TricksFrances Coronel
 
[FT-7][snowmantw] How to make a new functional language and make the world be...
[FT-7][snowmantw] How to make a new functional language and make the world be...[FT-7][snowmantw] How to make a new functional language and make the world be...
[FT-7][snowmantw] How to make a new functional language and make the world be...Functional Thursday
 
Clean Code Tutorial maXbox starter24
Clean Code Tutorial maXbox starter24Clean Code Tutorial maXbox starter24
Clean Code Tutorial maXbox starter24Max Kleiner
 
Text editors project
Text editors projectText editors project
Text editors projectMohit kumar
 
My programming final proj. (1)
My programming final proj. (1)My programming final proj. (1)
My programming final proj. (1)aeden_brines
 
Questions On The Code And Core Module
Questions On The Code And Core ModuleQuestions On The Code And Core Module
Questions On The Code And Core ModuleKatie Gulley
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202Mahmoud Samir Fayed
 
Flutter tutorial for Beginner Step by Step
Flutter tutorial for Beginner Step by StepFlutter tutorial for Beginner Step by Step
Flutter tutorial for Beginner Step by StepChandramouli Biyyala
 
Introduction to Software Development
Introduction to Software DevelopmentIntroduction to Software Development
Introduction to Software DevelopmentZeeshan MIrza
 
The Ring programming language version 1.3 book - Part 10 of 88
The Ring programming language version 1.3 book - Part 10 of 88The Ring programming language version 1.3 book - Part 10 of 88
The Ring programming language version 1.3 book - Part 10 of 88Mahmoud Samir Fayed
 
C language industrial training report
C language industrial training reportC language industrial training report
C language industrial training reportRaushan Pandey
 
Complete C programming Language Course
Complete C programming Language CourseComplete C programming Language Course
Complete C programming Language CourseVivek chan
 
Code Documentation. That ugly thing...
Code Documentation. That ugly thing...Code Documentation. That ugly thing...
Code Documentation. That ugly thing...Christos Manios
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller ColumnsJonathan Fine
 
A Docker-based Development Environment Even I Can Understand
A Docker-based Development Environment Even I Can UnderstandA Docker-based Development Environment Even I Can Understand
A Docker-based Development Environment Even I Can UnderstandJeremy Gimbel
 

Similar to Go Programming by Example_ Nho Vĩnh Share.pdf (20)

Fullstack Academy - Awesome Web Dev Tips & Tricks
Fullstack Academy - Awesome Web Dev Tips & TricksFullstack Academy - Awesome Web Dev Tips & Tricks
Fullstack Academy - Awesome Web Dev Tips & Tricks
 
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
 
[FT-7][snowmantw] How to make a new functional language and make the world be...
[FT-7][snowmantw] How to make a new functional language and make the world be...[FT-7][snowmantw] How to make a new functional language and make the world be...
[FT-7][snowmantw] How to make a new functional language and make the world be...
 
Clean Code Tutorial maXbox starter24
Clean Code Tutorial maXbox starter24Clean Code Tutorial maXbox starter24
Clean Code Tutorial maXbox starter24
 
Text editors project
Text editors projectText editors project
Text editors project
 
My programming final proj. (1)
My programming final proj. (1)My programming final proj. (1)
My programming final proj. (1)
 
Questions On The Code And Core Module
Questions On The Code And Core ModuleQuestions On The Code And Core Module
Questions On The Code And Core Module
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202
 
Flutter tutorial for Beginner Step by Step
Flutter tutorial for Beginner Step by StepFlutter tutorial for Beginner Step by Step
Flutter tutorial for Beginner Step by Step
 
Introduction to Software Development
Introduction to Software DevelopmentIntroduction to Software Development
Introduction to Software Development
 
The Ring programming language version 1.3 book - Part 10 of 88
The Ring programming language version 1.3 book - Part 10 of 88The Ring programming language version 1.3 book - Part 10 of 88
The Ring programming language version 1.3 book - Part 10 of 88
 
C language industrial training report
C language industrial training reportC language industrial training report
C language industrial training report
 
Srgoc dotnet
Srgoc dotnetSrgoc dotnet
Srgoc dotnet
 
Complete C programming Language Course
Complete C programming Language CourseComplete C programming Language Course
Complete C programming Language Course
 
Code Documentation. That ugly thing...
Code Documentation. That ugly thing...Code Documentation. That ugly thing...
Code Documentation. That ugly thing...
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller Columns
 
Golang workshop
Golang workshopGolang workshop
Golang workshop
 
Intro to Android Programming
Intro to Android ProgrammingIntro to Android Programming
Intro to Android Programming
 
A Docker-based Development Environment Even I Can Understand
A Docker-based Development Environment Even I Can UnderstandA Docker-based Development Environment Even I Can Understand
A Docker-based Development Environment Even I Can Understand
 
Oopp Lab Work
Oopp Lab WorkOopp Lab Work
Oopp Lab Work
 

More from Nho Vĩnh

CCNA Routing and Switching Complete Study Guide.pdf
CCNA Routing and Switching Complete Study Guide.pdfCCNA Routing and Switching Complete Study Guide.pdf
CCNA Routing and Switching Complete Study Guide.pdfNho Vĩnh
 
Python Cookbook_ Nho Vĩnh Share.pdf
Python Cookbook_ Nho Vĩnh Share.pdfPython Cookbook_ Nho Vĩnh Share.pdf
Python Cookbook_ Nho Vĩnh Share.pdfNho Vĩnh
 
C how to Program_ Nho Vĩnh Share.pdf
C how to Program_ Nho Vĩnh Share.pdfC how to Program_ Nho Vĩnh Share.pdf
C how to Program_ Nho Vĩnh Share.pdfNho Vĩnh
 
Python_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdf
Python_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdfPython_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdf
Python_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdfNho Vĩnh
 
MySQL for Python_ Nho Vĩnh Share.pdf
MySQL for Python_ Nho Vĩnh Share.pdfMySQL for Python_ Nho Vĩnh Share.pdf
MySQL for Python_ Nho Vĩnh Share.pdfNho Vĩnh
 
C++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh ShareC++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh ShareNho Vĩnh
 
C Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh Share
C Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh ShareC Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh Share
C Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh ShareNho Vĩnh
 
Data_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdf
Data_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdfData_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdf
Data_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdfNho Vĩnh
 
Artificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdf
Artificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdfArtificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdf
Artificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdfNho Vĩnh
 

More from Nho Vĩnh (9)

CCNA Routing and Switching Complete Study Guide.pdf
CCNA Routing and Switching Complete Study Guide.pdfCCNA Routing and Switching Complete Study Guide.pdf
CCNA Routing and Switching Complete Study Guide.pdf
 
Python Cookbook_ Nho Vĩnh Share.pdf
Python Cookbook_ Nho Vĩnh Share.pdfPython Cookbook_ Nho Vĩnh Share.pdf
Python Cookbook_ Nho Vĩnh Share.pdf
 
C how to Program_ Nho Vĩnh Share.pdf
C how to Program_ Nho Vĩnh Share.pdfC how to Program_ Nho Vĩnh Share.pdf
C how to Program_ Nho Vĩnh Share.pdf
 
Python_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdf
Python_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdfPython_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdf
Python_Programming_Language_For_Beginners_ Nho Vĩnh Share.pdf
 
MySQL for Python_ Nho Vĩnh Share.pdf
MySQL for Python_ Nho Vĩnh Share.pdfMySQL for Python_ Nho Vĩnh Share.pdf
MySQL for Python_ Nho Vĩnh Share.pdf
 
C++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh ShareC++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh Share
 
C Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh Share
C Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh ShareC Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh Share
C Programming_ Step By Step Beginner's To Experts _ Nho Vĩnh Share
 
Data_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdf
Data_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdfData_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdf
Data_Structure_and_Algorithms_Using_C++ _ Nho Vĩnh Share.pdf
 
Artificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdf
Artificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdfArtificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdf
Artificial_Intelligence__A_Modern_Approach_Nho Vĩnh Share.pdf
 

Recently uploaded

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 

Go Programming by Example_ Nho Vĩnh Share.pdf

  • 1.
  • 2.
  • 3.
  • 4. Copyright Go Programming by Example Agus Kurniawan 1st Edition, 2015 Copyright © 2015 Agus Kurniawan * Cover photo is credit to Fajar Ramadhany, Bataviasoft, http://bataviasoft.com/. ** Go logo is taken from https://blog.golang.org/gopher .
  • 5. Table of Contents Copyright Preface 1. Development Environment 1.1 Installation 1.2 Development Tools 1.3 Hello World 1.4 Go Packages 2. Go Programming Language 2.1 Common Rule 2.2 Variables 2.2.1 Declaring Variable 2.2.2 Assigning Variables 2.2.3 Demo 2.3 Comment 2.4 Arithmetic Operations 2.5 Mathematical Functions 2.6 Increment and Decrement 2.7 Getting Input from Keyboard 2.8 Comparison Operators 2.9 Logical Operators 2.10 Decision 2.10.1 if..then 2.10.2 switch..case 2.11 Iteration - for 2.12 Iteration - while 2.13 break and continue 3. Arrays, Slices and Maps 3.1 Array 3.2 Slice
  • 6. 3.3 Map 4. Functions 4.1 Creating A Simple Function 4.2 Function with Parameters 4.3 Function with Returning Value 4.4 Function with Multiple Returning Values 4.5 Function with Multiple Parameters and Returning Value 4.6 Closure Function 4.7 Recursion Function 4.8 Testing 5. Pointers 5.1 Pointer in Go 5.2 Demo: Singly Linked List 6. Structs and Methods 6.1 Structs 6.2 Methods 7. String Operations 7.1 Getting Started 7.2 Concatenating Strings 7.3 String To Numeric 7.4 Numeric to String 7.5 String Parser 7.6 Check String Data Length 7.7 Copy Data 7.8 Upper and Lower Case Characters 7.9 Testing A Program 8. File Operations 8.1 Getting Started 8.2 Writing Data Into A File 8.3 Reading Data From A File 8.4 Writing All
  • 7. 9. Error Handling and Logging 9.1 Error Handling 9.2 defer, panic(), and recover() 9.3 try..catch 9.4 Logging 10. Building Own Go Package 10.1 Creating Simple Module 10.2 Building Own Package 11. Concurrency 11.1 Getting Started 11.2 Goroutines 11.3 Synchronizing Goroutines 11.4 Channels 12. Encoding 12.1 Getting Started 12.2 Encoding Base64 12.3 Hexadecimal 12.4 JSON 12.5 XML 12.6 CSV 13. Hashing and Cryptography 13.1 Getting Started 13.2 Hashing 13.2.1 Hashing with MD5 13.2.2 Hashing with SHA256 13.2.3 Hashing with Key Using HMAC 13.2.4 Testing 13.3 Cryptography 13.3.1 Symmetric Cryptography 13.3.2 Asymmetric Cryptography 14. Database Programming
  • 8. 14.1 Database for Go 14.2 MySQL Driver for Go 14.3 Testing Connection 14.4 Querying 15. Socket Programming 15.1 Socket Module 15.2 Hello World 15.3 Client/Server Socket 15.3.1 Server Socket 15.3.2 Client Socket 15.3.3 Testing Source Code Contact
  • 9. Preface Go was created by Robert Griesemer, Rob Pike, and Ken Thompson at Google in 2007. This book is a reference to the Go programming language. It describes all the elements of the language and illustrates their use with code examples. Agus Kurniawan Berlin & Depok, February 2015
  • 10. 1. Development Environment This chapter explains introduction of Go. The official web of Go could be found on https://golang.org/. What is Go? Based on information from website, we could know what it is. Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
  • 11. 1.1 Installation Installation of Go application is easy. For Windows and Mac Platform, you download setup file from Go website, http://golang.org/doc/install. Run it and follow installation commands. The next step is to configure GOROOT path. For Windows platform, you can add GOROOT variable on Environment Variables. For Mac/Linux, you can it on your bash profile.
  • 12. For Windows platform, you can add GO installation path, for instance my Go installation path is c:/go/bin, into PATH variable on Environment Variables.
  • 13. After configured, you can verify Go version by typing this command on your Terminal or CMD for Windows. $ go version A sample output can be seen in Figure below, Mac platform.
  • 14. The output of program on Windows platform.
  • 15. 1.2 Development Tools Basically, you can use any text editor to write Go code. The following is a list of text editor: vim nano Intellij IDEA, https://www.jetbrains.com/idea/ Sublime text, http://www.sublimetext.com/ A sample screenshot for Intellij IDEA is shown in Figure below.
  • 16. 1.3 Hello World How to get started with Go? well, it is easy. Firstly, create a folder, called hello. $ mkdir hello $ cd hello Then, create a file, called main.go, on the hello folder. Write this code for main.go file. package main import "fmt" func main() { fmt.Println("Hello, go!") } Save this file. Then, back to your Terminal. You can build and run it. $ go build $ go run main.go In this case, it will generate an executable file based on your platform. A sample program output can be seen in Figure below.
  • 17. 1.4 Go Packages There are a lot of Go packages that you can use. The list of Go packages can seen on this link https://golang.org/pkg/. In this book, we will explore some Go standard packages. We also try to build own Go package.
  • 18. 2. Go Programming Language This chapter explains the basic of Go programming language.
  • 19. 2.1 Common Rule Go language uses “C family” as primary language but we don’t write “;” at the end of syntax. Here is the syntax rule: syntax_code1 syntax_code2 syntax_code3
  • 20. 2.2 Variables In this section, we explore how to define a variable and assign its value. 2.2.1 Declaring Variable To declare a variable called myvar and data type is data_type1, you can write the following script: var myvar data_type1 The following is a sample script to declare some variables. var str string var n, m int var mn float32 We also can define multiple variables as follows. var ( name string email string age int ) Once declared, these variables can be used to store any type data. 2.2.2 Assigning Variables Variable that you already declare can be assigned by a value. It can done using the equals sign (=). For example, variable str will assign a string value “Hello World”, you would write this: str = "Hello World" n = 10 m = 50 mn = 2.45 We also can declare a variable and assign its value. var city string = "London" var x int = 100
  • 21. Another option, we can declare a variable with defining data type using := syntax. Assign it with a value. country := "DE" val := 15 2.2.3 Demo For illustration for declaring variables using Go, create a folder, called vardemo. Then, create a file, called main.go. Write the following script for main.go. package main import "fmt" func main() { // declare variables var str string var n, m int var mn float32 // assign values str = "Hello World" n = 10 m = 50 mn = 2.45 fmt.Println("value of str= ",str) fmt.Println("value of n= ",n) fmt.Println("value of m= ",m) fmt.Println("value of mn= ",mn) // declare and assign values to variables var city string = "London" var x int = 100 fmt.Println("value of city= ",city) fmt.Println("value of x= ",x) // declare variable with defining its type country := "DE" val := 15 fmt.Println("value of country= ",country) fmt.Println("value of val= ",val)
  • 22. // define multiple variables var ( name string email string age int ) name = "john" email = "john@email.com" age = 27 fmt.Println(name) fmt.Println(email) fmt.Println(age) } Save this file. Then, try to build and run it. $ cd vardemo $ go build $ go run main.go A sample output can be seen in Figure below.
  • 23. 2.3 Comment You may explain how to work on your code with writing comments. To do it, you can use // and /* */ syntax. Here is sample code: // declare variables var str string var n, m int var mn float32 // assign values str = "Hello World" n = 10 m = 50 mn = 2.45 /* print the result */ fmt.Println("value of str= ",str)
  • 24. 2.4 Arithmetic Operations Go supports the same four basic arithmetic operations such as addition, subtraction, multiplication, and division. For testing, create a folder arithdemo. Then, create a file, called main.go. The following is the code illustration for basic arithmetic in main.go: package main import "fmt" func main() { // declare variables var a, b int // assign values a = 5 b = 10 // arithmetic operation // addition c := a + b fmt.Printf("%d + %d = %d n",a,b,c) // subtraction d := a - b fmt.Printf("%d - %d = %d n",a,b,d) // division e := float32(a) / float32(b) fmt.Printf("%d / %d = %.2f n",a,b,e) // multiplication f := a * b fmt.Printf("%d * %d = %d n",a,b,f) } Then, try to build and run it. $ cd arithdemo $ go build $ go run main.go The following is a sample output.
  • 25.
  • 26. 2.5 Mathematical Functions Go provides math library which you can read it on https://golang.org/pkg/math/. For illustration, we try to use several math functions. Create a folder, called mathdemo. Then, create a file, called main.go. Write the following code. package main import ( "fmt" "math" ) func main(){ a := 2.4 b := 1.6 c := math.Pow(a,2) fmt.Printf("%.2f^%d = %.2f n",a,2,c) c = math.Sin(a) fmt.Printf("Sin(%.2f) = %.2f n",a,c) c = math.Cos(b) fmt.Printf("Cos(%.2f) = %.2f n",b,c) c = math.Sqrt(a*b) fmt.Printf("Sqrt(%.2f*%.2f) = %.2f n",a,b,c) } Then, try to build and run it. $ cd mathdemo $ go build $ go run main.go The following is a sample output.
  • 27.
  • 28. 2.6 Increment and Decrement Go has special syntax for increment and decrement. ++ syntax for increment. a++ means a = a + 1 — syntay for decrement. a— means a = a - 1 For testing, create a folder, called incdec, and then create a file, called main.go. Write the following script. package main import "fmt" func main() { // declare variables var a = 4 // increment fmt.Printf("a = %d n",a) a = a + 1 fmt.Printf("a + 1 = %d n",a) a++ fmt.Printf("a++ = %d n",a) // decrement a = a - 1 fmt.Printf("a - 1 = %d n",a) a-- fmt.Printf("a-- = %d n",a) } Then, try to build and run it. $ cd incdec $ go build $ go run main.go The following is a sample output.
  • 29.
  • 30. 2.7 Getting Input from Keyboard In fmt library, it provides a feature to get input from keyboard. We can use Scanf(). For illustration, we calculate circle area. In this case, we need an input for radius value. Create a folder, called inputdemo. Then, create a file, called main.go, and write this script. package main import ( "fmt" "math" ) func main() { fmt.Println("Circle Area calculation") fmt.Print("Enter a radius value: ") var radius float64 fmt.Scanf("%f", &radius) area := math.Pi * math.Pow(radius,2) fmt.Printf("Circle area with radius %.2f = %.2f n",radius, area) } Then, try to build and run it. $ cd inputdemo $ go build $ go run main.go Entry an input for circle radius. The following is a sample output.
  • 31. 2.8 Comparison Operators You may determine equality or difference among variables or values. Here is the list of comparison operatos: == is equal to != is not equal > is greater than < is less than >= is greater than or equal to <= is less than or equal to This is sample code for comparison usage. package main import "fmt" func main() { var ( a = 2 b = 10 ) fmt.Println(a>b) fmt.Println(a<b) fmt.Println(a>=b) fmt.Println(a<=b) fmt.Println(a!=b) fmt.Println(a==b) } Build and run it. A sample output of the program can be seen in Figure below.
  • 32.
  • 33. 2.9 Logical Operators These operators can be used to determine the logic between variables or values. && and || or ! not Sample code: package main import "fmt" func main() { var ( a = 5 b = 8 ) fmt.Println(a>b && a!=b) fmt.Println(!(a>=b)) fmt.Println(a==b || a>b) } Build and run it. A sample output of the program can be seen in Figure below.
  • 34. 2.10 Decision There are two approaches to build decision on Go. We can use if..then and switch..case. 2.10.1 if..then Syntax model for if..then can be formulated as below: if conditional { // do something }else{ // do another job } conditional can be obtained by logical or/and comparison operations. package main import "fmt" func main() { var ( a = 5 b = 8 ) if a>b || a-b<a { fmt.Println("conditional-->a>b || a-b<a") }else{ fmt.Println("..another") } } Build and run it. A sample output of the program can be seen in Figure below.
  • 35. 2.10.2 switch..case switch..case can be declared as below: switch option { case option1: // do option1 job case option2: // do option2 job } Here is the sample code of switch..case usage: package main import "fmt" func main() { selected := 2 switch selected { case 0: fmt.Println("selected = 0") case 1: fmt.Println("selected = 1") case 2: fmt.Println("selected = 2") case 3: fmt.Println("selected = 3") default: fmt.Println("other..") } } Build and run it. A sample output of the program can be seen in Figure below.
  • 36.
  • 37. 2.11 Iteration - for Iteration operation is useful when we do repetitive activities. The following is for syntax. for initialization;conditional;increment/decrement { } For testing, write this script into a file, main.go. package main import "fmt" func main() { // iteration - for var i int for i=0;i<5;i++ { fmt.Println(i) } for j:=5;j<11;j++ { fmt.Println(j) } } Build and run it. A sample output of the program can be seen in Figure below.
  • 38.
  • 39. 2.12 Iteration - while Go doesn’t provide while syntax like “C family” programming language. We can use for which passes conditional value. Write this script for testing. package main import "fmt" func main() { // iteration - while // go doesn't provide while syntax. we can use for i := 0 for i<5 { fmt.Println(i) i++ } } Build and run it. A sample output of the program can be seen in Figure below.
  • 40. 2.13 break and continue break can be used to stop on the code point. Otherwise, continue can be used to skip some scripts. For illustration, we have a looping. The looping will be stopped using break if value = 3. Another sample, we can skip the iteration with value = 7 using continue syntax. Write this script. package main import "fmt" func main() { // iteration - for var i int for i=0;i<5;i++ { if i==3 { break } fmt.Println(i) } for j:=5;j<11;j++ { if j==7 { continue } fmt.Println(j) } } Build and run it. A sample output of the program can be seen in Figure below.
  • 41.
  • 42. 3. Arrays, Slices and Maps This chapter explains how to work with Go collection.
  • 43. 3.1 Array Go provides Array object for collection manipulation. We define our array variable as follows. var numbers[5] int var cities[5] string var matrix[3][3] int // array 2D For illustration, we can build a new project, called arraydemo, by creating a folder, called arraydemo. $ mkdir arraydemo $ cd arraydemo Then, create a file, main.go. Import Go packages for our program. package main import ( "fmt" "math/rand" ) In this program, we can try to define several array variables. Set their values and display them on Terminal. func main() { // define array fmt.Println("define arrays") var numbers[5] int var cities[5] string var matrix[3][3] int // array 2D // insert data fmt.Println(">>>>>insert array data") for i:=0;i<5;i++ { numbers[i] = i cities[i] = fmt.Sprintf("City %d",i) } // insert matrix data fmt.Println(">>>>>insert matrix data") for i:=0;i<3;i++ { for j:=0;j<3;j++ { matrix[i][j] = rand.Intn(100) }
  • 44. } // display data fmt.Println(">>>>>display array data") for j:=0;j<5;j++ { fmt.Println(numbers[j]) fmt.Println(cities[j]) } // display matrix data fmt.Println(">>>>>display matrix data") for i:=0;i<3;i++ { for j:=0;j<3;j++ { fmt.Println(matrix[i][j]) } } } Save this code. Build and run this program. $ go build $ go run main.go You can see a sample of program output, shown in Figure below.
  • 45.
  • 46. 3.2 Slice We can define an array without giving array length. Go uses Slice to do this case. To set array length, we can use make() function. For testing, we build a project, called slicedemo. $ mkdir slicedemo $ cd slicedemo Then, create a file, main.go, and write this code. package main import ( "fmt" "math/rand" ) func main() { // define slice fmt.Println("define slices") var numbers[] int numbers = make([]int,5) matrix := make([][]int,3*3) // insert data fmt.Println(">>>>>insert slice data") for i:=0;i<5;i++ { numbers[i] = rand.Intn(100) // random number } // insert matrix data fmt.Println(">>>>>insert slice matrix data") for i:=0;i<3;i++ { matrix[i] = make([]int,3) for j:=0;j<3;j++ { matrix[i][j] = rand.Intn(100) } } // display data fmt.Println(">>>>>display sclice data") for j:=0;j<5;j++ { fmt.Println(numbers[j]) } // display matrix data fmt.Println(">>>>>display sclice 2D data")
  • 47. for i:=0;i<3;i++ { for j:=0;j<3;j++ { fmt.Println(matrix[i][j]) } } } Save this code. Build and run this program. $ go build $ go run main.go A sample of program output can be seen in Figure below.
  • 48. 3.3 Map We can create an array with key-value. Go uses map() to implement key-value array. For illustration, we create a project, called mapdemo. $ mkdir mapdemo $ cd mapdemo We will define map variables. Then, set their values and dispay them on Terminal. Create a file, called main.go. Write this code. package main import ( "fmt" "math/rand" ) func main() { // define array fmt.Println("define map") products := make(map[string]int) customers := make(map[string]int) // insert data fmt.Println(">>>>>insert map data") products["product1"] = rand.Intn(100) products["product2"] = rand.Intn(100) customers["cust1"] = rand.Intn(100) customers["cust2"] = rand.Intn(100) // display data fmt.Println(">>>>>display map data") fmt.Println(products["product1"]) fmt.Println(products["product2"]) fmt.Println(customers["cust1"]) fmt.Println(customers["cust2"]) } Save this code. Build and run this program. $ go build $ go run main.go
  • 49. A sample of program output can be seen in Figure below.
  • 50. 4. Functions This chapter explains how to create function using Go.
  • 51. 4.1 Creating A Simple Function Declaring function in Go has format as follows. func function_name return_datatype { return foo } For illustration, we can build a new project, called arraydemo, by creating a folder, called arraydemo. $ mkdir arraydemo $ cd arraydemo Create a file, main.go. Then, import Go package. package main import ( "fmt" "math" ) To create a simple function, you can write this code in main.go file. func main(){ foo() } // a simple function func foo() { fmt.Println("foo() was called") }
  • 52. 4.2 Function with Parameters Sometimes you want to create a function with a parameter. You can implement it as follows. // a function with a parameter func circle_area(r float64){ area := math.Pi * math.Pow(r,2) fmt.Printf("Circle area (r=%.2f) = %.2f n",r, area) } If there are many parameters on function, we can define the function as below. // a function with parameters func calculate(a,b, c float64){ result := a*b*c fmt.Printf("a=%.2f, b=%.2f, c=%.2f = %.2f n",a, b, c, result) }
  • 53. 4.3 Function with Returning Value You may want to create function that has a return value. Look this code for sample illustration. // a function with parameters and a return value func advanced_calculate(a,b, c float64) float64 { result := a*b*c return result }
  • 54. 4.4 Function with Multiple Returning Values A function can return multiple returning values in Go. For instance, we return three values in Go function. A sample code can be written as below. // a function with parameters and multiple return values func compute(a,b, c float64, name string) (float64,float64,string) { result1 := a*b*c result2 := a + b + c result3 := result1 + result2 newName := fmt.Sprintf("%s value = %.2f", name,result3) return result1, result2, newName }
  • 55. 4.5 Function with Multiple Parameters and Returning Value You may want to unlimited parameters on function. It possible to implement it in Go. We can use … to define multiple parameters in a function. // a function with zero or more parameters and a return value func add(numbers ...int) int { result := 0 for _, number := range numbers { result += number } return result }
  • 56. 4.6 Closure Function We can define functions in a function. It’s called closure function. We can implement closure function in Go as follows. // a closure function func closure_func(name string){ hoo := func(a,b int){ result := a*b fmt.Printf("hoo() = %d n",result) } joo := func(a,b int) int { return a*b + a } fmt.Printf("closure_func(%s) was calledn",name) hoo(2,3) val := joo(5,8) fmt.Printf("val from joo() = %d n",val) }
  • 57. 4.7 Recursion Function Recursion function is a function where the solution to a problem depends on solutions to smaller instances of the same problem (as opposed to iteration). For illustration, we can implement Fibonacci problem using Go. The following is a sample code for Fibonacci solution in Go. // a recursion function func fibonacci(n int) int { if n==0{ return 0 }else if n==1 { return 1 } return (fibonacci(n-1) + fibonacci(n-2)) }
  • 58. 4.8 Testing We can write code again from section 4.1 to 4.7 and use them in main entry. Write this code on main.go file. package main import ( "fmt" "math" ) func main(){ foo() circle_area(2.56) calculate(2, 6.7, 5) val := advanced_calculate(2, 4.8, 7) fmt.Printf("advanced_calculate() = %.2f n",val) val1,val2,val3 := compute(6, 2.7, 1.4, "energy") fmt.Printf("val1=%.2f, val2=%.2f, val3="%s" n", val1, val2, val3) result := add(1,2,3,4,5,6,7,8,9,10,11) fmt.Printf("add() = %d n",result) closure_func("testing") ret := fibonacci(15) fmt.Printf("fibonacci() = %d n",ret) } // a simple function func foo() { fmt.Println("foo() was called") } // a function with a parameter func circle_area(r float64){ area := math.Pi * math.Pow(r,2) fmt.Printf("Circle area (r=%.2f) = %.2f n",r, area) } // a function with parameters func calculate(a,b, c float64){ result := a*b*c fmt.Printf("a=%.2f, b=%.2f, c=%.2f = %.2f n",a, b, c, result) } // a function with parameters and a return value func advanced_calculate(a,b, c float64) float64 { result := a*b*c
  • 59. return result } // a function with parameters and multiple return values func compute(a,b, c float64, name string) (float64,float64,string) { result1 := a*b*c result2 := a + b + c result3 := result1 + result2 newName := fmt.Sprintf("%s value = %.2f", name,result3) return result1, result2, newName } // a function with zero or more parameters and a return value func add(numbers ...int) int { result := 0 for _, number := range numbers { result += number } return result } // a closure function func closure_func(name string){ hoo := func(a,b int){ result := a*b fmt.Printf("hoo() = %d n",result) } joo := func(a,b int) int { return a*b + a } fmt.Printf("closure_func(%s) was calledn",name) hoo(2,3) val := joo(5,8) fmt.Printf("val from joo() = %d n",val) } // a recursion function func fibonacci(n int) int { if n==0{ return 0 }else if n==1 { return 1 } return (fibonacci(n-1) + fibonacci(n-2)) } Save this code.
  • 60. Build and run this program. $ go build $ go run main.go A sample of program output can be seen in Figure below.
  • 61. 5. Pointers This chapter we explore how to use Pointer in Go.
  • 62. 5.1 Pointer in Go A pointer is a programming language object, whose value refers directly to (or “points to”) another value stored elsewhere in the computer memory using its address, ref: http://en.wikipedia.org/wiki/Pointer_(computer_programming) . When we define x as int, we can x value by calling x = 1. To know the memory address of x, we can use &x. To test, we build a new project. Create a folder, called pointers. $ mkdir pointers $ cd pointers Creata a file, main.go, and write this code. package main import "fmt" func main(){ var x int x = 10 fmt.Println(x) // print a value of x fmt.Println(&x) // print address of x } Save this file. Try to build and run it. $ go build $ go run main.go
  • 63. You can see x has a value 10 and its memory address 0xC082002238. Memory address can be retrieved using & keyword. In Go, we can define data type as Pointer using *, for instance var x *int. We can set Pointer variable using *x = value. To set memory address on Pointer variable, we can use x = memory_address. For testing, we add the following code on main.go file. package main import "fmt" func main(){ var x int x = 10 fmt.Println(x) // print a value of x fmt.Println(&x) // print address of x // declare pointer var num *int val := new(int) num = new(int) *num = x // set value val = &x // set address fmt.Println("===pointer num===") fmt.Println(*num) // print a value of x fmt.Println(num) // print address of x fmt.Println("===pointer val===") fmt.Println(*val) // print a value of x fmt.Println(val) // print address of x } Save this file. Try to build and run it. A sample of program output is shown in Figure below.
  • 64.
  • 65. 5.2 Demo: Singly Linked List In this section, we can create a singly linked list from scratch. You can read your Data Structure book to understand what singly linked list is. You also read it on Wikipedia, http://en.wikipedia.org/wiki/Linked_list#Singly_linked_lists . Now we can create a singly linked list using Go. Firstly, we create folder, linkedlist. $ mkdir linkedlist $ cd linkedlist Create a file, main.go. Import Go package and define struct for Pointer. package main import ( "fmt" "math/rand" ) type Node struct { value int next *Node } next is Pointer variable which refers to memory address of the next Pointer variable. We create a function, add(), which we insert a new data on our singly linked list. The following is implementation of add() function. func add(list *Node,data int) *Node { if list==nil { list := new(Node) list.value = data list.next = nil return list }else{ temp := new(Node) temp.value = data temp.next = list list = temp return list } } We also can display a content of singly linked list. Create a function, display(), and write
  • 66. this code. func display(list *Node){ var temp *Node temp = list for temp!=nil { fmt.Println(temp.value) temp = temp.next } } In main entry, we define singly linked list as Pointer variable, called head. We add five data into a Pointer list. Then, we display all data. Write the following code for main() function. func main(){ var head *Node head = nil // add 5 data fmt.Println("=== insert 5 data=== ") n := 0 for n < 5 { fmt.Printf("data %dn",n) head = add(head,rand.Intn(100)) n++ } fmt.Println("=== display ===") display(head) } Save this file. Try to build and run it. $ go build $ go run main.go A sample of program output can be seen in Figure below.
  • 67.
  • 68. 6. Structs and Methods This chapter explains how to work with struct and method in Go.
  • 69. 6.1 Structs We can extend our object using struct. If you have experience in C/C++, we use struct approach in Go language. To define a struct, we can use struct keyword, for instance, we define struct_name for struct object. type struct_name struct { // fields } For illustration, we create a struct, Employee. Firstly, we build a new project by creating a folder, called structdemo. $ mkdir structdemo $ cd structdemo Then, create a file, called main.go. Firstly, we define our packages and a struct, Employee. package main import ( "fmt" "time" ) // define a struct type Employee struct { id int name string country string created time.Time } Employee struct has four fields such as id, name, country and created. To use a struct in Go, we can instance our struct object using new(). Then, we set its values. Write this code in entry point on main.go file. func main() { // declare variable var emp Employee newEmp := new(Employee)
  • 70. // set values emp.id = 2 emp.name = "Employee 2" emp.country = "DE" emp.created = time.Now() newEmp.id = 5 newEmp.name = "Employee 5" newEmp.country = "UK" newEmp.created = time.Now() // display fmt.Println("=====================") fmt.Println(emp.id) fmt.Println(emp.name) fmt.Println(emp.country) fmt.Println(emp.created) fmt.Println("=====================") fmt.Println(newEmp.id) fmt.Println(newEmp.name) fmt.Println(newEmp.country) fmt.Println(newEmp.created) } Save this file. Try to build and run it. $ go build $ go run main.go A sample of program output:
  • 71.
  • 72. 6.2 Methods We define methods in our struct object by passing struct object. For illustration, we create Circle struct object which has the following methods: display() area() circumference() moveTo() How to implement? Create a folder, called structmethod. $ mkdir structmethod $ cd structmethod The next step is to create a file, called main.go. Import our package and define Circle struct object. package main import ( "fmt" "math" ) // define a struct type Circle struct { x,y int r float64 } Circle struct has three fields: x, y and r. Basically, we can create struct method in the same way when you create a function. We pass our struct object on the front of method name. The following is implementation our struct methods. func (c Circle) display() { fmt.Printf("x=%d,y=%d,r=%.2fn",c.x,c.y,c.r) } func (c Circle) area() float64 { return math.Pi * math.Pow(c.r,2) } func (c Circle) circumference() float64 { return 2* math.Pi * c.r
  • 73. } func (c Circle) moveTo(newX,newY int) { c.x = newX c.y = newY } The last step is to use our struct method in main program. Write the following code. func main() { // methods shape := Circle{10,5,2.8} shape.display() fmt.Printf("area=%2.fn",shape.area()) fmt.Printf("circumference=%2.fn",shape.circumference()) shape.moveTo(5,5) shape.display() } Save this code. Build and run main.go on your Terminal. $ go build $ go run main.go A sample of program output:
  • 74. 7. String Operations This chapter explains how to work with String operation in Go.
  • 75. 7.1 Getting Started We already use string as data type. The following is a sample code to work with string data and print it on Terminal. // simple string demo var str string str = "Hello world" fmt.Println(str) In this section, we try to manipulate string data. We will explore several functions on strconv, http://golang.org/pkg/strconv/ and strings,http://golang.org/pkg/strings/ packages. Firstly, we build a new project by creating a folder, stringdemo. $ mkdir stringdemo $ cd stringdemo Create a file, called main.go. Import fmt, strcov and strings packages. package main import ( "fmt" "strconv" "strings" ) The next step is to explore how to work with string.
  • 76. 7.2 Concatenating Strings If you have a list of string, you can concatenate into one string. You can use + operator and fmt.Sprintf() function. Here is a sample code str1 := "hello" str2 := "world" str3 := str1 + str2 fmt.Println(str3) str4 := fmt.Sprintf("%s %s",str1,str2) fmt.Println(str4)
  • 77. 7.3 String To Numeric Sometime you want to do math operations but input data has string type. To convert string type into numeric, you can use strcov.ParseInt() for String to Int and strcov.ParseFloat() for string to Float. The following is a sample code to implement string to numeric conversion. fmt.Println("----demo String To Numeric----") str_val1 := "5" str_val2 := "2.8769" var err error var int_val1 int64 int_val1,err = strconv.ParseInt(str_val1,10,32) // base10, 64 size if err==nil { fmt.Println(int_val1) }else{ fmt.Println(err) } var float_val2 float64 float_val2,err = strconv.ParseFloat(str_val2,64) // 64 size if err==nil { fmt.Println(float_val2) }else{ fmt.Println(err) }
  • 78. 7.4 Numeric to String It is easy to convert numeric to String type, you can use fmt.Sprintf. You can get string type automatically. fmt.Println("----demo numeric to string----") num1 := 8 num2 := 5.872 var str_num1 string str_num1 = fmt.Sprintf("%d",num1) fmt.Println(str_num1) var str_num2 string str_num2 = fmt.Sprintf("%f",num2) fmt.Println(str_num2)
  • 79. 7.5 String Parser The simple solution to parsing String uses Split() with delimiter parameter. For example, you have String data with ; delimiter and want to parse it. Here is sample code fmt.Println("----demo String Parser----") data := "Berlin;Amsterdam;London;Tokyo" fmt.Println(data) cities := strings.Split(data, ";") for _, city := range cities { fmt.Println(city) }
  • 80. 7.6 Check String Data Length You can use len() to get the length of data. fmt.Println("----demo String Length----") str_data := "welcome to go" len_data := len(str_data) fmt.Printf("len=%d n",len_data)
  • 81. 7.7 Copy Data You may copy some characters from String data. To do it, you can use [start:end] syntax. Here is syntax format: fmt.Println("----demo copy data----") sample := "hello world, go!" fmt.Println(sample) fmt.Println(sample[0:len(sample)]) // copy all fmt.Println(sample[:5]) // copy 5 characters fmt.Println(sample[3:8]) // copy characters from index 3 until 8 fmt.Println(sample[len(sample)-5:len(sample)]) // 5 copy characters from t
  • 82. 7.8 Upper and Lower Case Characters In some situation, you want to get all string data in upper or lower case characters. This feature is built in String object. ToUpper() function is used to make whole string in upper case and ToLower() is used to make whole string in lower case. The following is a sample code to get upper and lower case characters. fmt.Println("----demo upper/lower characters----") message := "Hello World, GO!" fmt.Println(message) fmt.Println(strings.ToUpper(message)) // upper chars fmt.Println(strings.ToLower(message)) // upper chars
  • 83. 7.9 Testing A Program We can write our code in main.go completely as follows. package main import ( "fmt" "strconv" "strings" ) func main(){ // simple string demo var str string str = "Hello world" fmt.Println(str) // Concatenating str1 := "hello" str2 := "world" str3 := str1 + str2 fmt.Println(str3) str4 := fmt.Sprintf("%s %s",str1,str2) fmt.Println(str4) // String To Numeric fmt.Println("----demo String To Numeric----") str_val1 := "5" str_val2 := "2.8769" var err error var int_val1 int64 int_val1,err = strconv.ParseInt(str_val1,10,32) // base10, 64 size if err==nil { fmt.Println(int_val1) }else{ fmt.Println(err) } var float_val2 float64 float_val2,err = strconv.ParseFloat(str_val2,64) // 64 size if err==nil { fmt.Println(float_val2) }else{ fmt.Println(err) }
  • 84. // numeric to string fmt.Println("----demo numeric to string----") num1 := 8 num2 := 5.872 var str_num1 string str_num1 = fmt.Sprintf("%d",num1) fmt.Println(str_num1) var str_num2 string str_num2 = fmt.Sprintf("%f",num2) fmt.Println(str_num2) // String Parser fmt.Println("----demo String Parser----") data := "Berlin;Amsterdam;London;Tokyo" fmt.Println(data) cities := strings.Split(data, ";") for _, city := range cities { fmt.Println(city) } // String Data Length fmt.Println("----demo String Length----") str_data := "welcome to go" len_data := len(str_data) fmt.Printf("len=%d n",len_data) // copy data fmt.Println("----demo copy data----") sample := "hello world, go!" fmt.Println(sample) fmt.Println(sample[0:len(sample)]) // copy all fmt.Println(sample[:5]) // copy 5 characters fmt.Println(sample[3:8]) // copy characters from index 3 until 8 fmt.Println(sample[len(sample)-5:len(sample)]) // 5 copy characters from t // Upper and Lower Case Characters fmt.Println("----demo upper/lower characters----") message := "Hello World, GO!" fmt.Println(message) fmt.Println(strings.ToUpper(message)) // upper chars fmt.Println(strings.ToLower(message)) // upper chars } Save this code. Build and run main.go on your Terminal. $ go build $ go run main.go
  • 85. A sample of program output:
  • 86. 8. File Operations This chapter explains how to work with file operations.
  • 87. 8.1 Getting Started We can work with I/O file using io package, http://golang.org/pkg/io/ . For illustration, we can try to write and read text file. Firstly, we create a folder, called fileio. $ mkdir fileio $ cd fileio The next step is to build Go application to write and read a file.
  • 88. 8.2 Writing Data Into A File To write and read a file, we can use io package. In this section, we try to write data into a file. Create a file, called main.go, and put it on <go_project_root>/fileio folder. Firstly, we define our packages which we use. import ( "fmt" "io/ioutil" ) Then, create a function, called writeFile(). Write this code. func writeFile(message string) { bytes := []byte(message) ioutil.WriteFile("d:/temp/testgo.txt",bytes,0644) fmt.Println("created a file") } You can see that we can create a file using ioutil.WriteFile(). We pass data in byte array format. You can change file name and its path.
  • 89. 8.3 Reading Data From A File To read data from a file, we create a function, called readFile(). Write this code. func readFile(){ data, _ := ioutil.ReadFile("d:/temp/testgo.txt") fmt.Println("file content:") fmt.Println(string(data)) } To read a content of file, we can use ioutil.ReadFile(). It return array of string. Note: a file and its patch is similar to file on previous section.
  • 90. 8.4 Writing All To simply, we can write our code in main.go file as follows. package main import ( "fmt" "io/ioutil" ) func main() { // write data into a file fmt.Println("writing data into a file") writeFile("welcome to go") readFile() // read data from a file fmt.Println("reading data from a file") readFile() } func writeFile(message string) { bytes := []byte(message) ioutil.WriteFile("d:/temp/testgo.txt",bytes,0644) fmt.Println("created a file") } func readFile(){ data, _ := ioutil.ReadFile("d:/temp/testgo.txt") fmt.Println("file content:") fmt.Println(string(data)) } Save this file. Now you can build and run it. $ go build $ go run main.go A sample output of program is shown in Figure below.
  • 91.
  • 92. 9. Error Handling and Logging This chapter explains how to handle errors and exceptions that occur in Go application.
  • 93. 9.1 Error Handling Basically when we write a program and occur error on running, Go will catch program error. It will generate a panic. For illustration, we create a project by creating a folder, errorhandle. $ mkdir errorhandle $ cd errorhandle Then, create a file, main.go, and write this code. package main import ( "fmt" ) func main(){ calculate() } func calculate() { fmt.Println("----demo error handling---") a := 10 b := 0 c := 0 c = a/b fmt.Printf("result = %.2f n",c) fmt.Println("Done") } Now you can build and run it. $ go build $ go run main.go This program output is shown in Figure below.
  • 94.
  • 95. 9.2 defer, panic(), and recover() Go provide defer syntax to make sure our program run completely. panic() can be use to raise error on our program. For illustration, we add demoPanic() function on main.go from previous project. Then, we call demoPanic() in main entry. package main import ( "fmt" ) func main(){ demoPanic() } func demoPanic() { fmt.Println("----demo error handling---") defer func() { fmt.Println("do something") }() panic("this is a panic from demoPanic()") fmt.Println("This message will never show") } Now you can this program.
  • 96. You can see function under defer run completely. When we call panic(), Go will raise error on our program and then stopped this program. Now how to catch error on Go program? we can use recover() to catch error. Try to create calculaze2() function, and write this code. package main import ( "fmt" ) func main(){ calculate2() } func calculate2() {
  • 97. fmt.Println("----demo error handling---") c := 0 defer func() { a := 10 b := 0 c = a/b if error := recover(); error != nil { fmt.Println("Recovering….", error) fmt.Println(error) } }() fmt.Printf("result = %d n",c) fmt.Println("Done") } Now you can run this program.
  • 98. You can see the program occurred error but it can recover so the program can print “result” and “Done” at the end of program.
  • 99. 9.3 try..catch In this section, we explorer external library, Try/Catch/Finally, from https://github.com/manucorporat/try . We can use try..catch to handle error in Go. To install Go library from Github, you must instal git, http://git-scm.com/ . Download it based on your platform. If you use Windows platform, don’t forget to set it on PATH on Environment Variables. The next step is to configure GOPATH. It represents our workspace path, for instance, my workspace path is D:PE_PRESSeBookgo_progcodes. In Linux/Mac, you can define your own workspace path in under your account home path, for instance. Further information, you can read it on https://golang.org/doc/code.html . If you use Linux/Mac, you can define GOPATH using export command or you add it on your profile file. $ mkdir $HOME/go $ export GOPATH=$HOME/go If you use Windows platform, you open Environment Variables. You can open it from
  • 100. Advanced system settings. Then, click Environment Variables button. Add GOPATH on your user and System variables. For illustration, we create a project by creating a folder, trycatch. $ mkdir trycatch $ cd trycatch Now we can install trycatch library from Github. Type the following command. $ go get github.com/manucorporat/try
  • 101. If you use Windows platform and get error related to libcurl.dll, you must copy libcurl.dll from <installed_git_path>/bin folder to <installed_git_path>/libexec/git-core folder.
  • 102. Now you can write a program. Create a file, called main.go, and write this code. package main import ( "fmt" "github.com/manucorporat/try" ) func main() { try.This(func() { a := 10 b := 0 c := 0 c = a/b fmt.Printf("result = %.2f n",c) }).Finally(func() { fmt.Println("Done") }).Catch(func(_ try.E) { fmt.Println("exception catched") // print try.Throw() // rethrow current exception!!
  • 103. }) } Save this code. Now you can build and run this program. $ go build $ go run main.go A program output can be seen in Figure below.
  • 104. 9.4 Logging In previous section, we use fmt.Println() to print error message on console. Imagine there are many messages on console and we want to identify which error message is. Go package provides “log” to handle logging. For illustration, we create a project by creating a folder, logging. $ mkdir logging $ cd logging Then, try to create a file, main.go, and write this code. package main import ( "fmt" "log" "os" ) func main() { simpleLogging() } func simpleLogging(){ fmt.Println("-----------simple logging-----------") log.Println("Hello World") log.Println("This is a simple error") } Now you can build and run it. $ go build $ go run main.go This program output is shown in Figure below.
  • 105. We can modify our logging format by modifying log.Logger object. For illustration, create a function, called formattingLogging(), and write this code. func main() { formattingLogging() } func formattingLogging(){ fmt.Println("-----------formattingLogging-----------") var warning *log.Logger warning = log.New( os.Stdout, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile) warning.Println("This is warning message 1") warning.Println("This is warning message 2") } Now you can build and run this program. A sample output can be seen in Figure below. We also can save our logging messages into a file. For instance, we save them on
  • 106. myapp.log. Basically, we can open file using os.OpenFile(). Then, pass this object into log.Logger object. Try to create fileLogging() function and write this code. func main() { fileLogging() } func fileLogging(){ fmt.Println("-----------file logging-----------") file, err := os.OpenFile("d:/temp/myapp.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { fmt.Println("Failed to open log file") return } var logFile *log.Logger logFile = log.New( file, "APP: ", log.Ldate|log.Ltime|log.Lshortfile) logFile.Println("This is error message 1") logFile.Println("This is error message 2") logFile.Println("This is error message 3") fmt.Println("Done") } Note: You can change file path based on your platform. Now you can build and run this program. After that, you can open myapp.log file. You will see the logging message on this file.
  • 107.
  • 108. 10. Building Own Go Package This chapter explains how to build own Go Package
  • 109. 10.1 Creating Simple Module In this section, we create a simple module. We will call functions from external file (*.go) in the same package, main package. Firstly, create new project, called mymodule. $ mkdir mymodule $ cd mymodule Then, create a file, called simplemath.go. We define three functions. Write the following code. package main func Add(a,b int) int { return a+b } func Subtract(a,b int) int { return a-b } func Multiply(a,b int) int { return a*b } Note: Method name is written in Pascalcase, for instance HelloWorld(), DoProcessing(), IsEmpty(). Now we will call three function (simplemath.go) from main entry. Create a new file, called main.go, and write this code. package main import ( "fmt" ) func main(){ fmt.Println("access mymodule…") var c int c = Add(10,6) fmt.Printf("add()=%dn",c) c = Subtract(5,8) fmt.Printf("subtract()=%dn",c) c = Multiply(5,3)
  • 110. fmt.Printf("multiply()=%dn",c) } Save all. Now you can test to build and run the program. $ go build $ go run main.go simplemath.go A sample output can be seen in Figure below.
  • 111. 10.2 Building Own Package In previous program, we create a module in main package. We create a package and then use it in our program. The first thing we should do is to configure GOPATH. It represents our workspace path, for instance, my workspace path is D:PE_PRESSeBookgo_progcodes. In Linux/Mac, you can define your own workspace path in under your account home path, for instance. Further information, you can read it on https://golang.org/doc/code.html . If you use Linux/Mac, you can define GOPATH using export command or you add it on your profile file. $ mkdir $HOME/go $ export GOPATH=$HOME/go If you use Windows platform, you open Environment Variables. You can open it from Advanced system settings. Then, click Environment Variables button. Add GOPATH on your user and System variables. In this section, we organize our workspace as follows:
  • 112. –- $GOPATH ––-src –––-simplemodule –––-simplemoduletest For instance, we already been on GOPATH. Then, create src/simplemodule and src/simplemoduletest folders. $ mkdir src $ cd src $ mkdir simplemodule $ mkdir simplemoduletest A sample illustration for our lab path is shown in Figure below.
  • 113. Now you can create a file, called simplemath.go on simplemath folder. Write the following code. package simplemath
  • 114. func Add(a,b int) int { return a+b } func Subtract(a,b int) int { return a-b } func Multiply(a,b int) int { return a*b } Note: Method name is written in Pascalcase, for instance HelloWorld(), DoProcessing(), IsEmpty(). To compile our package, you can navigate to simplemodule directory, then call go build and install. $ cd simplemodule $ go build $ go install If success, it will create a folder, called pkg. You can see your compiled package file, for instance, simplemodule.a The next step is to use simplemodule package. Create a file, called main.go on simplemathtest folder.
  • 115. package main import ( "fmt" "simplemodule" ) func main(){ fmt.Println("access mymodule…") var c int c = simplemath.Add(5,8) fmt.Printf("add()=%dn",c) c = simplemath.Subtract(5,8) fmt.Printf("subtract()=%dn",c) c = simplemath.Multiply(5,3) fmt.Printf("multiply()=%dn",c) } Save all. Now you can compile and run this program. $ cd simplemathtest $ go build $ go run main.go You can see the sample output can be seen in Figure below.
  • 116. 11. Concurrency This chapter explains how to create concurrency in Go
  • 117. 11.1 Getting Started We can run a program or a function in background using Go. In this chapter, we explore several scenarios to build concurrency application.
  • 118. 11.2 Goroutines Basically, we can define our Go background using go..<program code>. For illustration, create new project, called goroutines. $ mkdir goroutines $ cd goroutines Create a file, maing.go, and write this code. package main import ( "fmt" "time" ) func main(){ fmt.Printf("goroutines demon") // run func in background go calculate() index := 0 // run in background go func() { for index < 6 { fmt.Printf("go func() index= %d n", index) var result float64 = 2.5 * float64(index) fmt.Printf("go func() result= %.2f n", result) time.Sleep(500 * time.Millisecond) index++ } }() // run in background go fmt.Printf("go printed in the backgroundn") // press ENTER to exit var input string fmt.Scanln(&input) fmt.Println("done") } func calculate() { i := 12 for i < 15 { fmt.Printf("calculate()= %d n", i) var result float64 = 8.2 * float64(i) fmt.Printf("calculate() result= %.2f n", result)
  • 119. time.Sleep(500 * time.Millisecond) i++ } } In this code, we try to run program in background for functions and lines of code. We use go statement to represent background process. Save all. Now you can test to build and run the program. $ go build $ go run main.go A sample output can be seen in Figure below. You can see the program is running randomly due to all codes run on background (concurrency).
  • 120. 11.3 Synchronizing Goroutines We can synchronize among background codes in Go. One of the solution is to use sync library. In this section, we use sync.Mutex.Lock and sync.Mutex.Unlock for synchronization. For illustration, create new project, called syncgoroutines. $ mkdir syncgoroutines $ cd syncgoroutines Create a file, main.go, and write this code. package main import ( "fmt" "sync" "math/rand" "time" ) type Task struct { value int executedBy string } var total int var task Task var lock sync.Mutex func main(){ fmt.Printf("synchronizing goroutines demon") total = 0 task.value = 0 task.executedBy = "" display() // run background go calculate() go perform() // press ENTER to exit var input string fmt.Scanln(&input) fmt.Println("done") } func calculate(){
  • 121. for total < 10 { lock.Lock() task.value = rand.Intn(100) task.executedBy = "from calculate()" display() total++ lock.Unlock() time.Sleep(500 * time.Millisecond) } } func perform(){ for total < 10 { lock.Lock() task.value = rand.Intn(100) task.executedBy = "from perform()" display() total++ lock.Unlock() time.Sleep(500 * time.Millisecond) } } func display(){ fmt.Println("--------------------------") fmt.Println(task.value) fmt.Println(task.executedBy) fmt.Println("--------------------------") } Save all. Now you can test to build and run the program. $ go build $ go run main.go A sample output can be seen in Figure below.
  • 122.
  • 123. 11.4 Channels We can create channels in Go and then we can communicate among Goroutines using these channel. For illustration, we create a channel which hold number data. To insert data in channel, we can use channel <-. Otherwise, we can get data from a channel using <- channel. For testing, create new project, called simplechannel. $ mkdir simplechannel $ cd simplechannel Create a file, main.go, and write this code. package main import ( "fmt" ) func main(){ fmt.Println("simple channel") // define a channel c := make(chan int) // run a function in background go func() { fmt.Println("goroutine process") c <- 10 // write data to a channel }() val := <-c // read data from a channel fmt.Printf("value: %dn",val) } Save all. Now you can test to build and run the program. $ go build $ go run main.go A sample output can be seen in Figure below.
  • 124.
  • 125. 12. Encoding This chapter explains how to work with encoding in Go
  • 126. 12.1 Getting Started In this chapter, we explore encoding package, http://golang.org/pkg/encoding/ . The following is a list of our demo to illustrate how to use encoding package: Base64 Hexadecimal JSON XML CSV For testing, you can create a new project, called encoding. $ mkdir encoding $ cd encoding Create a file, main.go. Firstly, we import our Go packages for the demo. Write this code. package main import ( "fmt" "encoding/base64" "encoding/hex" "encoding/json" "encoding/xml" "encoding/csv" "os" )
  • 127. 12.2 Encoding Base64 The first demo is to work with base64 encoding. We can use base64 package, http://golang.org/pkg/encoding/base64/ . To encode string to base64 string, we can use EncodeToString(). Otherwise, we can decode it using DecodeString() function. For testing, we encode a string message to base64. Then, we decode base64 message to original message. Create a function, called demoBase64(). Call this function to main entry. func main(){ message := "hello,go (*w3hu%#" demoBase64(message) } func demoBase64(message string) { fmt.Println("--------Demo encoding base64--------") fmt.Println("plaintext:") fmt.Println(message) encoding := base64.StdEncoding.EncodeToString([]byte(message)) fmt.Println("base64 msg:") fmt.Println(encoding) decoding, _ := base64.StdEncoding.DecodeString(encoding) fmt.Println("decoding base64 msg:") fmt.Println(string(decoding)) } Save all. Now you can test to build and run the program. $ go build $ go run main.go A sample output can be seen in Figure below.
  • 128.
  • 129. 12.3 Hexadecimal The second demo is to encode and decode string to Hexademical. We can use hex package, http://golang.org/pkg/encoding/hex/, to implement our demo. Create a function, called demoHex(). The following is implementation of encoding/decoding Hexadecimal. func main(){ message := "hello,go (*w3hu%#" demoHex(message) } func demoHex(message string) { fmt.Println("--------Demo encoding Hex--------") fmt.Println("plaintext:") fmt.Println(message) encoding := hex.EncodeToString([]byte(message)) fmt.Println("Hex msg:") fmt.Println(encoding) decoding, _ := hex.DecodeString(encoding) fmt.Println("decoding Hex msg:") fmt.Println(string(decoding)) } Save this code. Now you can build and run this program. A sample output can be seen in Figure below.
  • 130. 12.4 JSON The third demo is to construct and parse JSON data. In Go, we can use json package, http://golang.org/pkg/encoding/json/ . In this demo, we try to convert struct data to JSON data. Then, we can convert JSOn string to struct. Now you can create a function, called demoJson(), and write this code. func main(){ demoJson() } func demoJson(){ fmt.Println("--------Demo encoding json--------") type Employee struct { Id string `json:"id"` Name string `json:"name"` Email string `json:"email"` } // struct to json fmt.Println(">>>>struct to json….") emp := &Employee{Id:"12345",Name:"Michael",Email:"michael@email.com" b, err := json.Marshal(emp) if err != nil { fmt.Println(err) return } fmt.Println(string(b)) // json string to struct fmt.Println(">>>>json to struct….") var newEmp Employee str := `{"Id":"4566","Name":"Brown","Email":"brown@email.com"}` json.Unmarshal([]byte(str),&newEmp) fmt.Printf("Id: %sn",newEmp.Id) fmt.Printf("Name: %sn",newEmp.Name) fmt.Printf("Email: %sn",newEmp.Email) } Save this code. Now you can build and run this program. A sample output can be seen in Figure below.
  • 131.
  • 132. 12.5 XML The fourth demo is to read and write XML data. We xml package, http://golang.org/pkg/encoding/xml/ . In this demo, we construct XML from a struct which has nested struct. In XML data nested struct can be converted to XML attribute and value. Now you can create a function, called demoXml(), and write this code. func main(){ demoXml() } func demoXml(){ fmt.Println("--------Demo encoding xml--------") type EmployeeCountry struct { CountryCode string `xml:"code,attr"` // XML attribute: code CountryName string `xml:",chardata"` // XML value } type Employee struct { XMLName xml.Name `xml:"employee"` Id string `xml:"id"` Name string `xml:"name"` Email string `xml:"email"` Country EmployeeCountry `xml:"country"` } // struct to xml fmt.Println(">>>>struct to xml….") emp := &Employee{Id:"12345",Name:"Michael",Email:"michael@email.com" Country: EmployeeCountry{CountryCode:"DE",CountryName: b, err := xml.Marshal(emp) if err != nil { fmt.Println(err) return } fmt.Println(string(b)) // xml string to struct fmt.Println(">>>>xml to struct….") var newEmp Employee str := `<employee><id>555</id><name>Lee</name><email>lee@email.com</email> xml.Unmarshal([]byte(str),&newEmp) fmt.Printf("Id: %sn",newEmp.Id) fmt.Printf("Name: %sn",newEmp.Name) fmt.Printf("Email: %sn",newEmp.Email) fmt.Printf("CountryCode: %sn",newEmp.Country.CountryCode) fmt.Printf("CountryName: %sn",newEmp.Country.CountryName)
  • 133. } Save this code. Now you can build and run this program. A sample output can be seen in Figure below.
  • 134. 12.6 CSV The last demo is to read and write data CSV which is a collection of comma-separated data. We can access CSV file using csv package, http://golang.org/pkg/encoding/csv/ . For testing, we have a CSV file, demo.csv, with the following content. Employee 1;employee1@email.com;DE Employee 2;employee2@email.com;UK Employee 3;employee3@email.com;UK Employee 4;employee4@email.com;NL Employee 5;employee5@email.com;US Employee 6;employee6@email.com;JP Employee 7;employee7@email.com;DE Create a function, demoCsv(). This function will read CSV file, demo.csv, and convert these data to array of struct. After that, we write array of struct to a new CSV file, called employee.csv. The following is implementation of reading/writing CSV file. func main(){ demoCsv() } func demoCsv(){ fmt.Println("--------Demo encoding csv--------") type Employee struct { Name string Email string Country string }
  • 135. // read csv file to a array of struct fmt.Println(">>>>read a csv file and load to array of struct….") file, err := os.Open("D:/PE_PRESS/eBook/go_prog/codes/src/encoding/demo.cs if err != nil { fmt.Println(err) return } defer file.Close() reader := csv.NewReader(file) reader.FieldsPerRecord = 3 reader.Comma = ';' csvData, err := reader.ReadAll() if err != nil { fmt.Println(err) os.Exit(1) } var emp Employee var employees []Employee for _, item := range csvData { emp.Name = item[0] emp.Email = item[1] emp.Country = item[2] employees = append(employees, emp) fmt.Printf("name: %s email: %s country: %sn", item[0], item[1],item[ } fmt.Println(">>>>show all employee structs….") fmt.Println(employees) // write data to csv file fmt.Println(">>>>write data to a csv file….") csvFile, err := os.Create("D:/PE_PRESS/eBook/go_prog/codes/src/encoding/em if err != nil { fmt.Println("Error:", err) return } defer csvFile.Close() writer := csv.NewWriter(csvFile) writer.Comma = ';' for _, itemEmp := range employees { records := []string{itemEmp.Name,itemEmp.Email,itemEmp.Country} err := writer.Write(records) if err != nil { fmt.Println("Error:", err) return } } writer.Flush()
  • 136. fmt.Println(">>>>Done") } Note: You can change CSV file path. Save this code. Now you can build and run this program. A sample output can be seen in Figure below. If you open employee.csv, you get a content of employee data like a content of demo.csv file.
  • 137. 13. Hashing and Cryptography This chapter explains how to work with hashing and cryptography in Go
  • 138. 13.1 Getting Started Hashing is generating a value or values from a string of text using a mathematical function. Cryptography is the practice and study of techniques for secure communication in the presence of third parties (called adversaries), http://en.wikipedia.org/wiki/Cryptography . In this chapter, I don’t explain mathematical hashing and Cryptography. You can read those materials on textbooks. In this chapter, we explore how to work with hashing implementation using Go. The following is hashing algorithms which we use in this book: MD5 SHA256 Hashing with Key (HMAC) The next topic is to implement Cryptography using Go. We explore symmetric and asymmetric Cryptography. Firstly, we can create a new project, called cryptodemo. $ mkdir cryptodemo $ cd cryptodemo Create a file, main.go. Firstly, we import our Go packages for the demo. Write this code. package main import ( "fmt" "crypto/md5" "crypto/sha256" "crypto/hmac" "crypto/aes" "crypto/rsa" "crypto/cipher" "crypto/rand" "crypto/x509" "encoding/hex" "encoding/base64" "encoding/pem" "io" "io/ioutil" ) Let’s start to explore hashing and cryptography using Go.
  • 139. 13.2 Hashing Basically, you can explore how to implement hashing or hash function using Go via http://golang.org/pkg/crypto/ . In this section, we explore several hashing algorithms, for instance, MD5, SHA256 and HMAC. 13.2.1 Hashing with MD5 We can use MD5 using md5 package, http://golang.org/pkg/crypto/md5/ . To calculate a hash value from a text , we can call Sum() function. For illustration, we create a function, demoHash_md5(), and write this code. func demoHash_md5() { fmt.Println("--------Demo encoding hash using md5--------") message := "Hello world, go!" fmt.Println("plaintext:") fmt.Println(message) h := md5.New() h.Write([]byte(message)) hash_message := hex.EncodeToString(h.Sum(nil)) fmt.Println("hashing message:") fmt.Println(hash_message) } 13.2.2 Hashing with SHA256 The second demo is to implement hash function using SHA256. Go provides sha256 package, http://golang.org/pkg/crypto/sha256/, to implement hash function using SHA256. For illustration, we create a function, demoHash_sha256(), and write this code. func demoHash_sha256() { fmt.Println("--------Demo encoding hash using sha256--------") message := "Hello world, go!" fmt.Println("plaintext:") fmt.Println(message) h := sha256.New() h.Write([]byte(message))
  • 140. hash_message := hex.EncodeToString(h.Sum(nil)) fmt.Println("hashing message:") fmt.Println(hash_message) } 13.2.3 Hashing with Key Using HMAC A keyed-hash message authentication code (HMAC) is a specific construction for calculating a message authentication code (MAC) involving a cryptographic hash function in combination with a secret cryptographic key, http://en.wikipedia.org/wiki/Hash- based_message_authentication_code . In Go, we can hmac package, http://golang.org/pkg/crypto/hmac/ , to implement HMAC algorithm. For illustration, we create a function, demoHashKey(), and write this code. func demoHashKey(key,message string) { fmt.Println("--------Demo encoding hash with key: HMAC and sha256--------" fmt.Println("key:") fmt.Println(key) fmt.Println("plaintext:") fmt.Println(message) hmacKey := []byte(key) h := hmac.New(sha256.New, hmacKey) h.Write([]byte(message)) hash_message := hex.EncodeToString(h.Sum(nil)) fmt.Println("hashing message:") fmt.Println(hash_message) } 13.2.4 Testing Save all code for our demo on section 13.2.1, 13.2.2 and 13.2.3. To testing, we call these functions in main entry. Write this code. func main(){ demoHash_md5() demoHash_sha256() demoHashKey("mykey","Hello world, go!") } Save all.
  • 141. Now you can test to build and run the program. $ go build $ go run main.go A sample output can be seen in Figure below.
  • 142. 13.3 Cryptography In this section, we focus Symmetric and Asymmetric Cryptography. In Symmetric Cryptography, we use the same key to encrypt and decrypt. Otherwise, Asymmetric Cryptography uses different key to encrypt and decrypt. We explore these on the next section. 13.3.1 Symmetric Cryptography There are many algorithms to implement Symmetric Cryptography. In this section, we use AES algorithm. The Advanced Encryption Standard (AES) is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001, http://en.wikipedia.org/wiki/Advanced_Encryption_Standard. For illustration, we create two functions, encrypt_symmetric_crpyto() and decrypt_symmetric_crpyto(). The following is implementation of encrypt_symmetric_crpyto(). func encrypt_symmetric_crpyto(key,message string) string { fmt.Println("--------Demo encrypt encrypt_symmetric_crpyto--------") if len(key)!=16 && len(key)!=24 && len(key)!=32 { fmt.Println("key must 16,24,32 byte length") return "" } bc, err := aes.NewCipher([]byte(key)) if err != nil { panic(err) } text := []byte(message) ciphertext := make([]byte, aes.BlockSize+len(text)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } cfb := cipher.NewCFBEncrypter(bc, iv) cfb.XORKeyStream(ciphertext[aes.BlockSize:], text) return base64.StdEncoding.EncodeToString(ciphertext) } Explanation:
  • 143. Define a key. It should be 16, 24, or 32 key length Instantiate AES using NewCipher() with passing key value Calculate IV value Encrypt message in array of byte format by calling NewCFBEncrypter() The result is be encoded to base64 string The following is implementation of encrypt_symmetric_crpyto(). func decrypt_symmetric_crpyto(key,message string) string { fmt.Println("--------Demo decrypt decrypt_symmetric_crpyto--------") if len(key)!=16 && len(key)!=24 && len(key)!=32 { fmt.Println("key must 16,24,32 byte length") return "" } encrypted,_ := base64.StdEncoding.DecodeString(message) bc, err := aes.NewCipher([]byte(key)) if err != nil { panic(err) } if len(encrypted) < aes.BlockSize { panic("ciphertext too short") } iv := encrypted[:aes.BlockSize] encrypted = encrypted[aes.BlockSize:] cfb := cipher.NewCFBDecrypter(bc, iv) cfb.XORKeyStream(encrypted, encrypted) return string(encrypted) } Explanation: Define a key. It should be 16, 24, or 32 key length Instantiate AES using NewCipher() with passing key value Calculate IV value Encrypt message in array of byte format by calling NewCFBDecrypter() The result is be encoded to string Now we can call these functions in main entry. Write this code. func main(){ // symmetric crypto key := "this is key 1234" message := "Hello world, go!" encrypted := encrypt_symmetric_crpyto(key,message)
  • 144. fmt.Println("message:") fmt.Println(message) fmt.Println("key:") fmt.Println(key) fmt.Println("encrypted:") fmt.Println(encrypted) decrypted := decrypt_symmetric_crpyto(key,encrypted) fmt.Println("encrypted message:") fmt.Println(encrypted) fmt.Println("key:") fmt.Println(key) fmt.Println("decrypted:") fmt.Println(decrypted) } Now you can build and run it. A sample output can be seen in Figure below. 13.3.2 Asymmetric Cryptography The common algorithm to implement Asymmetric Cryptography is RSA which is widely used for secure data transmission. You read a brief description in Wikipedia, http://en.wikipedia.org/wiki/RSA_(cryptosystem) . Go has library for RSA implementation. In this section, we try to implement RSA using Go. The following is our scenario:
  • 145. Generate RSA keys (public and private keys) Save these keys to two files (public and private key files) For encryption, we use public key file For decryption, we use private key file We store public and private keys into a file in PEM data encoding. We can use pem package from Go, http://golang.org/pkg/encoding/pem/ . To generate public and private keys for RSA, we create a function, generateRSAkeys(). After generated keys, we save these keys to files. The following is implementation for generating keys. func generateRSAkeys(){ fmt.Println("Generating RSA keys….") // change files and their paths privKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/private.rsa pubKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/public.rsa.k // generate RSA keys privateKey, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { panic(err) } // extract private and public keys from RSA keys privASN1 := x509.MarshalPKCS1PrivateKey(privateKey) pubASN1, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey) if err != nil { panic(err) } // store private and public keys into files privBytes := pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", Bytes: privASN1, }) pubBytes := pem.EncodeToMemory(&pem.Block{ Type: "RSA PUBLIC KEY", Bytes: pubASN1, }) ioutil.WriteFile(privKeyFile, privBytes, 0644) ioutil.WriteFile(pubKeyFile, pubBytes, 0644) fmt.Println("Done") }
  • 146. This code will generate two files, private.rsa.key and public.rsa.key files. To encrypt data, we create a function, encrypt_asymmetric_crypto(). Firstly, we load public key. Then, encrypt the message using RSA. The following is code implementation for encrypt_asymmetric_crypto() function. func encrypt_asymmetric_crypto(message string) string { fmt.Println("--------Demo encrypt encrypt_asymmetric_crypto--------" // public key file pubKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/public.rsa.k // read public key from file pubBytes, err := ioutil.ReadFile(pubKeyFile) if err != nil { panic(err) } pubBlock, _ := pem.Decode(pubBytes) if pubBlock == nil { fmt.Println("Failed to load public key file") return "" } // Decode the RSA public key publicKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes) if err != nil { fmt.Printf("bad public key: %s", err) return "" } // encrypt message msg := []byte(message) encryptedmsg, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.Publ if err != nil { panic(err) } return base64.StdEncoding.EncodeToString(encryptedmsg) } To decrypt data, we create a function, decrypt_asymmetric_crypto(). Firstly, we load private key. Then, decrypt the message using RSA. The following is code implementation for decrypt_asymmetric_crypto() function. func decrypt_asymmetric_crypto(message string) string { fmt.Println("--------Demo decrypt decrypt_asymmetric_crypto--------" // private key file privKeyFile := "D:/PE_PRESS/eBook/go_prog/codes/src/cryptodemo/private.rsa
  • 147. // read private key from file privBytes, err := ioutil.ReadFile(privKeyFile) if err != nil { panic(err) } privBlock, _ := pem.Decode(privBytes) if privBlock == nil { fmt.Println("Failed to load private key file") return "" } // Decode the RSA private key privateKey, err := x509.ParsePKCS1PrivateKey(privBlock.Bytes) if err != nil { fmt.Printf("bad public key: %s", err) return "" } // encrypt message encrypted,_ := base64.StdEncoding.DecodeString(message) decrypteddmsg, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encrypt if err != nil { panic(err) } return string(decrypteddmsg) } Save all. Now you can implement our functions to main entry. Write this code. func main(){ // asymmetric crypto generateRSAkeys() plainText := "Hello world, go!" fmt.Println("plainText:") fmt.Println(plainText) rsa_encrypted := encrypt_asymmetric_crypto(plainText) fmt.Println("encrypted:") fmt.Println(rsa_encrypted) rsa_decrypted := decrypt_asymmetric_crypto(rsa_encrypted) fmt.Println("decrypted:") fmt.Println(rsa_decrypted) } Now you can build and run it. A sample output can be seen in Figure below.
  • 148. You can open public.rsa.key to see our RSA public key value. You can also open private.rsa.key to see our RSA private key value.
  • 149.
  • 150. 14. Database Programming This chapter explains how to build database application using Go.
  • 151. 14.1 Database for Go Go can communicate with database server through database driver. Go provides generic interfaces for database drive on http://golang.org/pkg/database/ . We must install database driver and Go database package before we start to develop database application. In this chapter, I only focus on MySQL scenario.
  • 152. 14.2 MySQL Driver for Go We use Go-MySQL-Driver for database driver. Further information about this driver, please visit on https://github.com/go-sql-driver/mysql . To install Go-MySQL-Driver, you can try to write this command in terminal $ go get github.com/go-sql-driver/mysql After finished, we can do testing.
  • 153. 14.3 Testing Connection In this section, we try to connect MySQL database. Firstly, we can create a new project, called mysqldemo. $ mkdir mysqldemo $ cd mysqldemo Create a file, main.go. Firstly, we import our Go packages for the demo. Write this code. package main import ( "fmt" "database/sql" _ "github.com/go-sql-driver/mysql" ) Firstly, we can start to create simple Go application to connect to mysql database. Write this code func main(){ testConnection() } func testConnection(){ // change database user and password db, err := sql.Open("mysql",string("user:password@tcp(127.0.0.1:3306)/rese if err != nil { panic(err) } err = db.Ping() // test connection if err != nil { panic(err.Error()) } fmt.Println("connected") defer db.Close() } change host, user, and password based on your mysql database configuration and authentication. Save all. Now you can test to build and run the program. $ go build $ go run main.go
  • 154. A sample output can be seen in Figure below.
  • 155. 14.4 Querying In this section, we try to insert data into a table. The following is our table scheme on MySQL. Here is sample code to insert data into mysql database using Go. func main(){ insertData() } func insertData(){ db, err := sql.Open("mysql",string("researcher:researcher@tcp(127.0.0.1:33 if err != nil { panic(err) } err = db.Ping() // test connection if err != nil { panic(err.Error()) } fmt.Println("connected") // prepare development stmt, err := db.Prepare("INSERT INTO sensordevice(deviceid,temperature,hum if err != nil { panic(err) } defer stmt.Close() fmt.Println("inserting data…") for i := 0; i < 10; i++ { _, err = stmt.Exec(2,0.2*float64(i),0.6*float64(i),0.5*float64(i), if err != nil { panic(err) } } fmt.Println("done") defer db.Close() }
  • 156. After finished, we can do testing. You can verify this data into your table.
  • 157. 15. Socket Programming This chapter explains how to create socket application using Go.
  • 158. 15.1 Socket Module We can create application based on socket stack using net package. You can find it for further information on http://golang.org/pkg/net/. I recommend you to read some books or websites about the concept of socket.
  • 159. 15.2 Hello World To get started, we create a simple application to get a list of IP Address in local computer. We can use net package and call Interfaces() to get a list of network interfaces in our local computer. Each network interface provides information about IP address. In this section, we try to get local IP Address. Firstly, we can create a new project, called netdemo. $ mkdir netdemo $ cd netdemo Create a file, main.go. Then, write this code. package main import ( "fmt" "net" ) func main(){ ifaces, err := net.Interfaces() if err!=nil { panic(err) } fmt.Println("getting local IP Address…") for _, i := range ifaces { addrs, err := i.Addrs() if err!=nil { panic(err) } for _, addr := range addrs { switch v := addr.(type) { case *net.IPAddr: if v.String()!="0.0.0.0"{ fmt.Println(v.String()) } } } } } Save this code. Try to build and run it. The following is a sample program output which runs on Windows:
  • 160.
  • 161. 15.3 Client/Server Socket Now we create a client/server socket using Go. We will use net package to build client/server application. For illustration, we create server and client. 15.3.1 Server Socket How to create server socket? It is easy. The following is a simple algorithm how to build server socket create server socket listen incoming client on the specific port if client connected, listen incoming data and then disconnect from client In this section, we build server app. Firstly, we can create a new project, called netserver. $ mkdir netserver $ cd netserver Create a file, main.go. Write this code. package main import ( "fmt" "net" "os" ) const ( SVR_HOST = "localhost" SVR_PORT = "9982" SVR_TYPE = "tcp" ) func main() { fmt.Println("server is running") svr, err := net.Listen(SVR_TYPE, SVR_HOST+":"+SVR_PORT) if err != nil { fmt.Println("Error listening:", err.Error()) os.Exit(1) } defer svr.Close() fmt.Println("Listening on " + SVR_HOST + ":" + SVR_PORT) fmt.Println("Waiting client…") for {
  • 162. conn, err := svr.Accept() if err != nil { fmt.Println("Error accepting: ", err.Error()) os.Exit(1) } fmt.Println("client connected") go handleClient(conn) } } func handleClient(conn net.Conn) { buff := make([]byte, 1024) msgLen, err := conn.Read(buff) if err != nil { fmt.Println("Error reading:", err.Error()) } fmt.Println("Received: ",string(buff[:msgLen])) conn.Close() } It uses port 9982. You can change it. 15.3.2 Client Socket Client socket is client application that connects to server and then sends/receives data from/to server. We should know about IP address and port from target server. We can call Dial() to connect to server. Use Write() for sending data. In this section, we build client app. Firstly, we can create a new project, called netclient. $ mkdir netclient $ cd netclient Create a file, main.go. Write this code. package main import ( "fmt" "net" ) const ( SVR_HOST = "localhost" SVR_PORT = "9982"
  • 163. SVR_TYPE = "tcp" ) func main() { fmt.Println("client is running") conn, err := net.Dial(SVR_TYPE, SVR_HOST+":"+SVR_PORT) if err != nil { panic(err) } fmt.Println("send data") _, err = conn.Write([]byte("message from client")) defer conn.Close() } 15.3.3 Testing Now we can test our client/server application. Firstly, we run server application and then execute client application. Here is sample of program output for server application: Here is sample of program output for client application:
  • 164. Source Code You can download source code on http://www.aguskurniawan.net/book/go_cd.zip .
  • 165. Contact If you have question related to this book, please contact me at aguskur@hotmail.com . My blog: http://blog.aguskurniawan.net