# Golang Notes
## Declare
### Data Type
```go
// --- Data Type --- //
var a int
var b int = 1
const a int
var [name] [type]
// type: int, bool, string, float32, float64
a, b = b, a
a := 1 // local variable, no need data type
foo, bar := "Hello", 100
const (
a = 1
b
c = 2
d
)
// 1 1 2 2
```
### Array & Slice
```go
var example [3]int
var example = [3]int{}
var example = [3]int{1,2,3}
var example = [5]int{1,2} //partially initialized
var example = [...]int{1,2}
```
```go
people := make([]string, 0)
people = append(people, "Aaron")
people = append(people, "Jim")
fmt.Println(people) // [Aaron Jim]
```
### iota
```go
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
*// 0 1 2 3 4 5 6*
```
### Complex
```go
c1 := complex(2, 3)
fmt.Println(c1) // (2+3i)
fmt.Println(real(c1), imag(c1)) // 2 3
```
### Function
```go
package main
import "fmt"
func main() {
func() {
fmt.Println("Hello anonymous")
}()
func(i, j int) {
fmt.Println(i + j)
}(1, 2)
}
//##################################################################//
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(add(3, 2))
}
//##################################################################//
func main() {
add := func(x int, y int) int {
return x + y
}
fmt.Println(add(3, 5))
}
//##################################################################//
func add(x, y int) (ans int) {
ans = x + y
return
// return ans
}
```
### Struct
```go
package main
type student struct {
name string
height float64
}
func main() {
a := student{name: "student1", height: 100.0}
a := student{"student1",100.0}
b := &student{"student2", 200.1}
c := new(student)
c.name = "student3"
c.height = 169.9
var d student
d.name = ("student4")
d.height = 175.8
p := struct{
name string
height float64
}{name: "student5", height:170.1}
}
```
```go
package main
type student struct {
name string
height float64
contact contactInfo
}
type contactInfo struct {
email string
phoneNumber string
}
func main() {
a := student{name: "student1", height: 100.0}
a := student{"student1",100.0}
fmt.Printf("%+v", a)
b := &student{"student2", 200.1}
c := new(student)
c.name = "student3"
c.height = 169.9
var d student
d.name = ("student4")
d.height = 175.8
p := struct{
name string
height float64
}{name: "student5", height:170.1}
}
```
```go
package main
import "fmt"
type Student struct {
name string
height float64
contact contactType
}
type contactType struct {
email string
phoneNumber string
}
func main() {
info1 := contactInfo{"mark123@mail.com", "0912345678"}
stu1 := &Student{"Mark", 178.1, info1}
fmt.Println(stu1.name, stu1.contact.email)
}
```
### Function in Struct
```go
type Student struct {
name string
height float64
}
func (s Student) getHeight() {
fmt.Println(s.height)
}
func (s *Student) setHeight(h float64) { // Pointer
s.height = h
}
func main() {
s1 := Student{"Morris", 176.4}
s1.setHeight(177.0)
s1.getHeight()
}
```
### Pointer
```go
func plus_10(a *int) {
*a = *a + 10
}
func main() {
score := 75
plus_10(&score)
fmt.Println(score) //85
}
```
### Map (dict like)
```go
var colors map[string]string
colors := map[string]string{}
colors := map[string]string{
"1": "red",
"2": "orenge",
"3": "yellow",
}
delete(colors, "3")
for k, v := range colors {
fmt.Println(k, ": ", v)
}
colors := make(map[string]int)
```
### Interface
```go
package main
import "fmt"
**type Animal interface {
Eat()
}**
type Monkey struct {
Name string
}
func (m *Monkey) Eat() {
fmt.Printf("%s is eating bananas.\n", m.Name)
}
func main() {
monkey := Monkey{Name: "Mkey"}
monkey.Eat()
}
```
## ****Goroutine (thread)****
```go
func main() {
**//runtime.GOMAXPROCS(1) // maximum number of CPUs**
**go** Print("X") // start a thread
**go** Print("O")
time.Sleep(time.Second * 2)
}
func Print(s string) {
for i := 0; i < 50; i++ {
time.Sleep(time.Microsecond * 1)
fmt.Print(s)
}
}
```
```go
package main
import (
"fmt"
"sync"
"time"
)
func main() {
**var wg sync.WaitGroup**
for i := 0; i < 5; i++ {
**wg.Add(1)**
**go worker(i, &wg)**
}
**wg.Wait() // Wait for all Goroutines to finish**
fmt.Println("All workers have finished")
}
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // Signal that this Goroutine is done
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second) // Simulate some work
fmt.Printf("Worker %d done\n", id)
}
```
### Channel (Queue like)
```go
// ----- Buffered ----- //
ch := make(chan int, 1)
ch <- 5 // add value to channel
fmt.Println(<-ch) // **pop** value and print
fmt.Println( len(ch) ) // get length
fmt.Println( cap(ch) ) // get capital
// ----- Unbuffered ----- //
ch := make(chan int)
go func() {
ch <- 1
}()
fmt.Println(<-ch)
```
### mux.Lock (sync lock)
```go
type SafeNumber struct {
v int
mux **sync.Mutex**
}
func main() {
total := SafeNumber{v:0}
for i := 0; i < 1000; i++ {
go func(){
**total.mux.Lock()**
total.v++
**total.mux.Unlock()**
}()
}
time.Sleep(time.Second)
total.mux.Lock()
fmt.Println(total.v)
total.mux.Unlock()
}
```
### Select
```go
ch := make(chan string)
go func() {
time.Sleep(time.Second) //模擬費時運算
ch <- "FINISH"
}()
for { // unlimit loop
select {
case (<-ch):
fmt.Println("main完成")
return
default:
fmt.Println("waiting...")
time.Sleep(500 * time.Millisecond)
}
}
```
## Example
### Web
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
type HtmlData struct {
Title string
Content string
}
func test(c *gin.Context) {
data := HtmlData{"Title1", "Content1"}
c.HTML(http.StatusOK, "index.html", data)
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("template/*")
r.GET("/", test)
r.Run(":8080")
}
```