Agus Kurniawan - Go Programming by Example
Agus Kurniawan - Go Programming by Example
Go Programming by Example
Agus Kurniawan
1st Edition, 2015
Copyright 2015 Agus Kurniawan
* Cover photo is credit to Fajar Ramadhany, Bataviasoft, http://bataviasoft.com/.
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
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
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
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
2.2 Variables
In this section, we explore how to define a variable and assign its value.
Once declared, these variables can be used to store any type data.
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)
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)
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)
}
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)
}
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
}
2.10.2 switch..case
switch..case can be declared as below:
switch option {
case option1:
// do option1 job
case option2:
// do option2 job
}
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
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])
}
}
}
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
// 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])
}
}
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"])
}
4. Functions
For illustration, we can build a new project, called arraydemo, by creating a folder, called
arraydemo.
$ mkdir arraydemo
$ cd arraydemo
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")
}
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.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 called\n",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))
}
5. Pointers
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
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
}
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 %d\n",n)
head = add(head,rand.Intn(100))
n++
}
fmt.Println("=== display ===")
display(head)
}
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)
}
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
}
}
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.f\n",shape.area())
fmt.Printf("circumference=%2.f\n",shape.circumference())
shape.moveTo(5,5)
shape.display()
}
7. String Operations
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"
)
// 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
8. File Operations
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.
This chapter explains how to handle errors and exceptions that occur in Go application.
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() {
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, dont 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_PRESS\eBook\go_prog\codes. 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.
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!!
})
}
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
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")
}
After that, you can open myapp.log file. You will see the logging message on this file.
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
}
fmt.Printf("multiply()=%d\n",c)
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go simplemath.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.
- $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
Now you can create a file, called simplemath.go on simplemath folder. Write the
following code.
package simplemath
If success, it will create a folder, called pkg. You can see your compiled package file, for
instance, simplemodule.a
package main
import (
"fmt"
"simplemodule"
)
func main(){
fmt.Println("access mymodule")
var c int
c = simplemath.Add(5,8)
fmt.Printf("add()=%d\n",c)
c = simplemath.Subtract(5,8)
fmt.Printf("subtract()=%d\n",c)
c = simplemath.Multiply(5,3)
fmt.Printf("multiply()=%d\n",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
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
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
You can see the program is running randomly due to all codes run on background
(concurrency).
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
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
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: %d\n",val)
}
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
12. 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"
)
Save all.
Now you can test to build and run the program.
$ go build
$ go run main.go
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: %s\n",newEmp.Id)
fmt.Printf("Name: %s\n",newEmp.Name)
fmt.Printf("Email: %s\n",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))
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
}
fmt.Println(">>>>Done")
}
If you open employee.csv, you get a content of employee data like a content of demo.csv
file.
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"
)
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.
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.
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.
Explanation:
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.
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.")
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--------"
// encrypt message
msg := []byte(message)
encryptedmsg, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.Publ
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(encryptedmsg)
}
// 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.
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
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(){
// 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()
}
In this section, we build server app. Firstly, we can create a new project, called netserver.
$ mkdir netserver
$ cd netserver
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:
Source Code
Contact