switch num := number(); { //num is not a constant case num < 50: fmt.Printf("%d is lesser than 50\n", num) fallthrough case num < 100: fmt.Printf("%d is lesser than 100\n", num) fallthrough case num < 200: fmt.Printf("%d is lesser than 200", num) } }
数组和切片
1 2 3 4
var a [3]int// 整形数组,长度为3 a := [3]int{10, 20, 30} //[10 20 30] a := [3]int{10} //[10 0 0] a := [...]int{10, 20, 30} //[10 20 30],长度由编译时决定
数组是值类型
数组的遍历,可以通过for循环和range语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
package main
import"fmt"
funcmain() { a := [...]float64{67.7, 89.8, 21, 78} for i := 0; i < len(a); i++ { //looping from 0 to the length of the array fmt.Printf("%d th element of a is %.2f\n", i, a[i]) } sum := float64(0) for i, v := range a {//range returns both the index and value fmt.Printf("%d the element of a is %.2f\n", i, v) sum += v } fmt.Println("\nsum of all elements of a",sum) }
funcfind(num int, nums ...int) { fmt.Printf("type of nums is %T\n", nums) found := false for i, v := range nums { if v == num { fmt.Println(num, "found at index", i, "in", nums) found = true } } if !found { fmt.Println(num, "not found in ", nums) } fmt.Printf("\n") } funcmain() { nums := []int{89, 90, 95} find(89, nums...) }
字典
是 引用 类型,通过make函数创建
1
personSalary := make(map[string]int)
字典的操作。 通过 value, ok := map[key] ** 来判断key是否存在与map中;通过for range**来遍历
funcmain() { personSalary := make(map[string]int) personSalary["steve"] = 12000 personSalary["jamie"] = 15000 personSalary["mike"] = 9000 employee := "jamie" fmt.Println("Salary of", employee, "is", personSalary[employee]) newEmp := "joe" value, ok := personSalary[newEmp] if ok == true { fmt.Println("Salary of", newEmp, "is", value) } else { fmt.Println(newEmp,"not found") } for key, value := range personSalary { fmt.Printf("personSalary[%s] = %d\n", key, value) } }
字符串
字符串是字节的切片。用引号包含。字符串是不可变的
rune Unicode中超出UTF-8范围的编码字符,可以通过rune来表示
指针
存储变量地址的变量,通过 *T 来定义指针
1 2
b := 255 var a *int = &b
通过 new 函数创建 指针
1 2 3 4 5 6 7 8 9 10 11 12
package main
import ( "fmt" )
funcmain() { size := new(int) fmt.Printf("Size value is %d, type is %T, address is %v\n", *size, size, size) *size = 85 fmt.Println("New size value is", *size) }
指针作为函数参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
package main
import ( "fmt" )
funcchange(val *int) { *val = 55 } funcmain() { a := 58 fmt.Println("value of a before function call is",a) b := &a change(b) fmt.Println("value of a after function call is", a) }
type SalaryCalculator interface { CalculateSalary() int }
type Permanent struct { empId int basicpay int pf int }
type Contract struct { empId int basicpay int }
//salary of permanent employee is sum of basic pay and pf func(p Permanent)CalculateSalary()int { return p.basicpay + p.pf }
//salary of contract employee is the basic pay alone func(c Contract)CalculateSalary()int { return c.basicpay }
/* total expense is calculated by iterating though the SalaryCalculator slice and summing the salaries of the individual employees */ functotalExpense(s []SalaryCalculator) { expense := 0 for _, v := range s { expense = expense + v.CalculateSalary() } fmt.Printf("Total Expense Per Month $%d", expense) }
funcproducer(chnl chanint) { for i := 0; i < 10; i++ { chnl <- i } close(chnl) } funcmain() { ch := make(chanint) go producer(ch) //可以通过v, ok := <-ch 读取通道数据。与下二选一 for { v, ok := <-ch if ok == false { break } fmt.Println("Received ", v, ok) } //可以通过 for range 读取通道数据。与上二选一 for v := range ch { fmt.Println("Received ",v) } }
funcmain() { no := 3 var wg sync.WaitGroup for i := 0; i < no; i++ { wg.Add(1) go process(i, &wg) } wg.Wait() fmt.Println("All go routines finished executing") }
type Job struct { id int randomno int } type Result struct { job Job sumofdigits int }
var jobs = make(chan Job, 10) var results = make(chan Result, 10)
funcdigits(number int)int { sum := 0 no := number for no != 0 { digit := no % 10 sum += digit no /= 10 } time.Sleep(2 * time.Second) return sum } funcworker(wg *sync.WaitGroup) { for job := range jobs { output := Result{job, digits(job.randomno)} results <- output } wg.Done() } funccreateWorkerPool(noOfWorkers int) { var wg sync.WaitGroup for i := 0; i < noOfWorkers; i++ { wg.Add(1) go worker(&wg) } wg.Wait() close(results) } funcallocate(noOfJobs int) { for i := 0; i < noOfJobs; i++ { randomno := rand.Intn(999) job := Job{i, randomno} jobs <- job } close(jobs) } funcresult(done chanbool) { for result := range results { fmt.Printf("Job id %d, input random no %d , sum of digits %d\n", result.job.id, result.job.randomno, result.sumofdigits) } done <- true } funcmain() { startTime := time.Now() noOfJobs := 100 go allocate(noOfJobs) done := make(chanbool) go result(done) noOfWorkers := 10 createWorkerPool(noOfWorkers) <-done endTime := time.Now() diff := endTime.Sub(startTime) fmt.Println("total time taken ", diff.Seconds(), "seconds") }
funcmain() { ch := make(chanstring) go process(ch) for { time.Sleep(1000 * time.Millisecond) select { case v := <-ch: fmt.Println("received value: ", v) return default: fmt.Println("no value received") } }
} //output no value received no value received no value received no value received no value received no value received no value received no value received no value received no value received received value: process successful
死锁和default case。以下例子中,如果不添加default,会造成死锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package main
import"fmt"
funcmain() { ch := make(chanstring) select { case <-ch: default: fmt.Println("default case executed") } } //output defaultcase executed
package main import ( "fmt" "sync" ) var x = 0 funcincrement(wg *sync.WaitGroup, m *sync.Mutex) { m.Lock() x = x + 1 m.Unlock() wg.Done() } funcmain() { var w sync.WaitGroup var m sync.Mutex for i := 0; i < 1000; i++ { w.Add(1) go increment(&w, &m) } w.Wait() fmt.Println("final value of x", x) }
package main import ( "fmt" "sync" ) var x = 0 funcincrement(wg *sync.WaitGroup, ch chanbool) { ch <- true x = x + 1 <- ch wg.Done() } funcmain() { var w sync.WaitGroup ch := make(chanbool, 1) for i := 0; i < 1000; i++ { w.Add(1) go increment(&w, ch) } w.Wait() fmt.Println("final value of x", x) }
type website struct { posts []post } func(w website)contents() { fmt.Println("Contents of Website\n") for _, v := range w.posts { v.details() fmt.Println() } }
funcmain() { author1 := author{ "Naveen", "Ramanathan", "Golang Enthusiast", } post1 := post{ "Inheritance in Go", "Go supports composition instead of inheritance", author1, } post2 := post{ "Struct instead of Classes in Go", "Go does not support classes but methods can be added to structs", author1, } post3 := post{ "Concurrency", "Go is a concurrent language and not a parallel one", author1, } w := website{ posts: []post{post1, post2, post3}, } w.contents() }
funccalculateNetIncome(ic []Income) { var netincome int = 0 for _, income := range ic { fmt.Printf("Income From %s = $%d\n", income.source(), income.calculate()) netincome += income.calculate() } fmt.Printf("Net income of organisation = $%d", netincome) }
funclargest(nums []int) { defer finished() fmt.Println("Started finding largest") max := nums[0] for _, v := range nums { if v > max { max = v } } fmt.Println("Largest number in", nums, "is", max) }
funcprintA(a int) { fmt.Println("value of a in deferred function", a) } funcmain() { a := 5 defer printA(a) a = 10 fmt.Println("value of a before deferred function call", a)
}
//output value of a before deferred function call 10 value of a in deferred function 5
函数存在多个defer调用时,他们被加入了一个栈。后进先出(LIFO)次序
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package main
import ( "fmt" )
funcmain() { name := "Naveen" fmt.Printf("Original String: %s\n", string(name)) fmt.Printf("Reversed String: ") for _, v := range []rune(name) { defer fmt.Printf("%c", v) } }
错误处理
error是一个接口类型,定义如下
1 2 3
type error interface { Error() string }
通过断言,根据错误类别字段获取错误信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package main
import ( "fmt" "os" )
funcmain() { f, err := os.Open("/test.txt") if err, ok := err.(*os.PathError); ok { fmt.Println("File at path", err.Path, "failed to open") return } fmt.Println(f.Name(), "opened successfully") }
funcmain() { addr, err := net.LookupHost("golangbot123.com") if err, ok := err.(*net.DNSError); ok { if err.Timeout() { fmt.Println("operation timed out") } elseif err.Temporary() { fmt.Println("temporary error") } else { fmt.Println("generic error: ", err) } return } fmt.Println(addr) }
自定义错误
使用New函数创建自定义错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package errors
// New returns an error that formats as the given text. funcNew(text string)error { return &errorString{text} }
// errorString is a trivial implementation of error. type errorString struct { s string } //error 接口实现 func(e *errorString)Error()string { return e.s }
funcfullName(firstName *string, lastName *string) { defer fmt.Println("deferred call in fullName") if firstName == nil { panic("runtime error: first name cannot be nil") } if lastName == nil { panic("runtime error: last name cannot be nil") } fmt.Printf("%s %s\n", *firstName, *lastName) fmt.Println("returned normally from fullName") }
funcmain() { defer fmt.Println("deferred call in main") firstName := "Elon" fullName(&firstName, nil) fmt.Println("returned normally from main") }
//output deferred call in fullName deferred call in main panic: runtime error: last name cannot be nil
funcrecoverName() { if r := recover(); r!= nil { fmt.Println("recovered from ", r) } }
funcfullName(firstName *string, lastName *string) { defer recoverName() if firstName == nil { panic("runtime error: first name cannot be nil") } if lastName == nil { panic("runtime error: last name cannot be nil") } fmt.Printf("%s %s\n", *firstName, *lastName) fmt.Println("returned normally from fullName") }
funcmain() { defer fmt.Println("deferred call in main") firstName := "Elon" fullName(&firstName, nil) fmt.Println("returned normally from main") }
//output recovered from runtime error: last name cannot be nil returned normally from main deferred call in main
funcmain() { a := func() { fmt.Println("hello world first class function") } a() fmt.Printf("%T", a) func() { fmt.Println("hello world first class function") }() func(n string) { fmt.Println("Welcome", n) }("Gophers") }
用户定义函数类型
1
type add func(a int, b int)int
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package main
import ( "fmt" )
type add func(a int, b int)int
funcmain() { var a add = func(a int, b int)int { return a + b } s := a(5, 6) fmt.Println("Sum", s) }
函数作为参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
package main
import ( "fmt" )
funcsimple(a func(a, b int)int) { fmt.Println(a(60, 7)) }
funcmain() { f := func(a, b int)int { return a + b } simple(f) }
函数作为返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
package main
import ( "fmt" )
funcsimple()func(a, b int)int { f := func(a, b int)int { return a + b } return f }
funcmain() { s := simple() fmt.Println(s(60, 7)) }
闭包,捕获上下文变量
1 2 3 4 5 6 7 8 9 10 11 12
package main
import ( "fmt" )
funcmain() { a := 5 func() { fmt.Println("a =", a) }() }
funcmain() { f, err := os.Create("lines") if err != nil { fmt.Println(err) f.Close() return } d := []string{"Welcome to the world of Go1.", "Go is a compiled language.", "It is easy to learn Go."}
for _, v := range d { fmt.Fprintln(f, v) if err != nil { fmt.Println(err) return } } err = f.Close() if err != nil { fmt.Println(err) return } fmt.Println("file written successfully") }
funcproduce(data chanint, wg *sync.WaitGroup) { n := rand.Intn(999) data <- n wg.Done() }
funcconsume(data chanint, done chanbool) { f, err := os.Create("concurrent") if err != nil { fmt.Println(err) return } for d := range data { _, err = fmt.Fprintln(f, d) if err != nil { fmt.Println(err) f.Close() done <- false return } } err = f.Close() if err != nil { fmt.Println(err) done <- false return } done <- true }
funcmain() { data := make(chanint) done := make(chanbool) wg := sync.WaitGroup{} for i := 0; i < 100; i++ { wg.Add(1) go produce(data, &wg) } go consume(data, done) gofunc() { wg.Wait() close(data) }() d := <-done if d == true { fmt.Println("File written successfully") } else { fmt.Println("File writing failed") } }