Skip to content

Instantly share code, notes, and snippets.

@mingen-pan
Last active November 16, 2020 16:49
Show Gist options
  • Save mingen-pan/170a79709065df8ebd7a84149e1c9016 to your computer and use it in GitHub Desktop.
Save mingen-pan/170a79709065df8ebd7a84149e1c9016 to your computer and use it in GitHub Desktop.
Basic Go examples
package tutorial
import (
"fmt"
"math/rand"
"strconv"
"sync"
"testing"
"time"
)
func TestGoBasic(t *testing.T) {
// Define variable
// name and type, different from C.
var a int
// Type inference
// Think about the auto in C++
b := 2
a = b + 1
// If-else statement
// No need to use parenthesis
if a > 0 {
fmt.Println("I am good")
} else {
fmt.Println("I am bad")
}
// static array
arr := [3]int{1, 2, 3}
for i, num := range arr {
fmt.Printf("arr[%v]= %v\n", i, num)
}
// Dynamic Array
dynArray := make([]int, 10)
fmt.Printf("len(dynArray) = %d\n", len(dynArray)) // size = 10
dynArray = make([]int, 0, 10)
fmt.Printf("len(dynArray) = %d, cap(dynArray)= %d\n",
len(dynArray), cap(dynArray)) // size = 0, capacity = 10
for i := 0; i < 10; i++ {
dynArray = append(dynArray, i*i)
}
fmt.Printf("len(dynArray) = %d, cap(dynArray)= %d\n",
len(dynArray), cap(dynArray)) // size = 10, capacity = 10
// dynamic map
myMap := make(map[string]string)
myMap["key"] = "value"
myMap = map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
for k, v := range myMap {
fmt.Printf("map[%s]=%s\n", k, v)
}
}
func sleepAndPrint(num int) {
time.Sleep(time.Duration(num) * time.Millisecond)
fmt.Print(num, " ")
}
func TestGoRoutine(t *testing.T) {
arr := []int{5, 3, 2, 1, 4, 10, 12, 6}
// Lambda Expression is allowed in Go
// The slice []int is reference, so there is no need to use pointer.
sleepSort := func(arr []int) {
for _, num := range arr {
go sleepAndPrint(num)
}
}
sleepSort(arr)
time.Sleep(1 * time.Second)
fmt.Println()
}
func sleepAndReturn(num int, c chan int) {
time.Sleep(time.Duration(num) * time.Millisecond)
c <- num
}
func TestChannel(t *testing.T) {
arr := []int{5, 3, 2, 1, 4, 10, 12, 6}
// Lambda Expression is allowed in Go
// The slice []int is reference, so there is no need to use pointer.
sleepSort := func(arr []int) {
// make a channel with size of the array
c := make(chan int, len(arr))
for _, num := range arr {
go sleepAndReturn(num, c)
}
for i := 0; i < len(arr); i++ {
num := <-c
fmt.Print(num, " ")
}
}
sleepSort(arr)
fmt.Println()
}
type Entry struct {
// Capitalization means public
Index int
// private variable can be only accessed by the same package
val string
}
// Type method
func (entry Entry) increaseIndexByOneFake() {
entry.Index++
}
func (entry *Entry) increaseIndexByOneReal() {
entry.Index++
}
func increaseIndexByOneAnotherWay(entry *Entry) {
entry.Index++
}
func TestPointer(t *testing.T) {
entry := Entry{
Index: 0,
val: "val",
}
fmt.Println("index: " + strconv.Itoa(entry.Index))
entry.increaseIndexByOneFake()
fmt.Println("index: " + strconv.Itoa(entry.Index))
entry.increaseIndexByOneReal()
fmt.Println("index: " + strconv.Itoa(entry.Index))
increaseIndexByOneAnotherWay(&entry)
fmt.Println("index: " + strconv.Itoa(entry.Index))
}
func printType(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("%v is int\n", v)
case string:
fmt.Printf("%v is string\n", v)
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func TestTypeCasting(t *testing.T) {
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
f, ok := i.(float64)
fmt.Println(f, ok)
//f = i.(float64) // panic
//fmt.Println(f)
printType(10)
printType("abc")
printType(nil)
printType(12.2)
}
func goodLockHabit(lock *sync.Mutex) int {
lock.Lock()
defer lock.Unlock()
// Early stop
// Don't have to unlock before every return
if rand.Int()%2 == 0 {
return 1
}
// more logic
// ...
return 0
}
func badLockHabit(lock *sync.Mutex) int {
lock.Lock()
// Early stop
if rand.Int()%2 == 0 {
return 1
}
// more logic
// ...
lock.Unlock()
return 0
}
func TestLock(t *testing.T) {
lock := sync.Mutex{}
for i := 0; i < 10; i++ {
// There will be no dead lock don't worry
goodLockHabit(&lock)
}
defer func() {
if recover() != nil {
fmt.Println("A dead lock happens")
}
}()
for i := 0; i < 10; i++ {
// you will lock it twice sometime
badLockHabit(&lock)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment