学习golang注意点:

  1. 导的包必须使用;或者使用_未使用的包,作用是调用该包下的初始化方法。
  2. 局部变量声明必须使用。
  3. go语言的包和java的相似,包名.变量访问

1. 初识go语言

1.1 Hello World

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("hello world");
  5. }

1.2 go 数据类型

布尔:

  1. var a bool = true
  2. var b bool = false

整型:

整型分为有符号和无符号的类型

8, 16 ,32 分别代表位数

int : 根据系统决定是32位还64位

int8 : 1个字节,-128~127 相当于java中的short;

int16 : 2个字节,-215 ~ 215 -1

int32 : 4个字节 -231 ~231 - 1

int64: 8个字节-263 ~263 - 1

uint : .....

无符号整形都是取值0~216 - 1

  1. var a int = -3
  2. var b uint = 3 //uint类型不可以为负数

浮点型:

  1. var a float32 = 100.0
  2. var b float64 = 100.00 //默认

字符类型

golang中的字符使用的是字节保存的,本质就是一个int32类型

  1. var a byte = 'a'
  2. var b byte = 'c'
  3. fmt.Print(a, "===", b) //输出的是该字节对应的字节码: 97===99
  4. fmt.Printf("%c === %c", a, b) // a === c

字符串型:

  1. var str string = "hello world"
  2. //多行字符串,不需要使用+来连接多行
  3. var str2 string = `a
  4. asda asdasdadsadasd `

复数类型:

complex64 是两个float32组成 complex128两个float64组成

  1. var a complex64 = 10 + 3i
  2. var b complex128= 10 + 3i //默认

相关操作

  1. var v= complex(2 , 3) //构造1个复数,
  2. a := real(v) //返回复数实部 2
  3. b := image(v) 返回复数虚部 3

rune类型:

  1. // rune is an alias for int32 and is equivalent to int32 in all ways. It is
  2. // used, by convention, to distinguish character values from integer values.
  3. //int32的别名,几乎在所有方面等同于int32
  4. //它用来区分字符值和整数值
  5. type rune = int32

1.3 变量常量

局部变量:

属于函数或者方法;声明之后必须使用

  1. var a = 3;
  2. var b int = 3;
  3. c := 3

全局变量

b := 10 这种全局变量声明是错误的

全局变量的概念:隶属于,声明之后可以不使用

  1. var a int
  2. var (
  3. c int
  4. d string
  5. )
  6. var e = 3

常量

局部

  1. const a = 3

全局

  1. const a int = 10
  2. const b = 20
  3. const (
  4. d int = 10
  5. e string = "ss"
  6. f = 30
  7. )

1.5 字符串相关操作

golang中string底层是通过byte数组实现的,byte使用utf-8编码标识的Unicode文本,每个汉字占3个字节

  1. 求长度
  1. func strDemo() {
  2. fmt.Println(len("hello")) //5
  3. fmt.Println(len("中")) //3
  4. fmt.Println(len([]rune("中"))) //1, 正确获取中文字符串长度
  5. }
  1. 字符串遍历
  1. //对中文无法支持
  2. func strEach() {
  3. str := "hello world"
  4. for i := 0; i < len(str); i ++ {
  5. //fmt.Print(str[i] ,"\t") // 104 101 108 108 111 32 119 111 114 108 100
  6. //讲字节编码转为字符串输出
  7. fmt.Printf("%c\t", str[i]) //h e l l o w o r l d
  8. }
  9. }
  1. func strEach() {
  2. str := "hello world 中国"
  3. for i, s := range str {
  4. //0 h1 e2 l3 l4 o5 6 w7 o8 r9 l10 d11 12 中15 国
  5. fmt.Print(i, "\t", string(s))
  6. }
  7. }
  8. //这个可以正确的输出索引
  9. func strEachRune() {
  10. str := "中国人民"
  11. for i, s := range []rune(str) {
  12. fmt.Println(i, string(s))
  13. }
  14. }
  1. 其他操作
  1. str := "中国人民, hello world"
  2. index := strings.Index(str, "国") //存在则 index > -1, 否则 == -1 此时index=-3
  3. split := strings.Split(str, ",")
  4. replace := strings.Replace(str, "o", "2", 1) //第三个参数标识替换几个,小于0,则替换所有
  5. result := strings.EqualFold("中国", "中国2") //不区分大小写
  6. fmt.Println("中国" == "中国H") //区分大小写, 同strings.Compare()5

1.6 相互转换

1.6.1 基本数据

golang基本数据数据之间的转换可使用公:T(i) 进行相互转换

  1. //数据之间的相互转换
  2. func transfer() {
  3. //
  4. var i int = 10
  5. var j float64 = 11.30
  6. x := float64(i)
  7. y := int(j)
  8. fmt.Print(x, "\t", y) //10 11
  9. }

1.6.2 string <=> 基本数据类型

  1. 基本类型=>string

fmt.Sprintf(format string, param interface{})

  1. func stringTrans() {
  2. var i int = 10
  3. var flag bool = true
  4. int_str := fmt.Sprintf("%d", i)
  5. bool_str := fmt.Sprintf("%t", flag)
  6. fmt.Println(int_str)
  7. fmt.Println(bool_str)
  8. }

strconv

  1. func stringStrco() {
  2. var i int = 10000
  3. var flag bool = true
  4. var price float64 = 130.32
  5. formatInt := strconv.FormatInt(int64(i), 10) //等价: strconv.Itoa(i)
  6. formatBool := strconv.FormatBool(flag)
  7. formatFloat := strconv.FormatFloat(price, 'f', 10, 64)
  8. fmt.Println(formatInt)
  9. fmt.Println(formatBool)
  10. fmt.Println(formatFloat)
  11. }
  1. String=>基本数据类型
  1. func strToBase() {
  2. str_flag := "true"
  3. str_age := "20"
  4. str_price := "20.33"
  5. flag, _ := strconv.ParseBool(str_flag)
  6. age, _ := strconv.ParseInt(str_age, 10, 64)
  7. age_int, _ := strconv.Atoi(str_age)
  8. price, _ := strconv.ParseFloat(str_price, 64)
  9. fmt.Println(flag)
  10. fmt.Println(age)
  11. fmt.Println(price)
  12. fmt.Println(age_int)
  13. }

1.6.3 字节数组和字符串

  1. func byteAndStr() {
  2. str := "hello world, 中国"
  3. data := []byte(str)
  4. s := string(data)
  5. fmt.Println(s)
  6. fmt.Println(data)
  7. }

1.7 时间

  1. 获取时间
  1. func timeOperate() {
  2. cur := time.Now()
  3. curT := time.Now().Unix() //获取时间戳
  4. fmt.Println(cur) //2019-01-30 20:40:16.410689 +0800 CST m=+0.000353772
  5. fmt.Println(curT) //1548852137
  6. }
  1. 时间和字符串转换
  1. func formatTime() {
  2. format := time.Now().Format("2006-01-02 15:04:05")
  3. //时间戳转时间
  4. var timestamp int64 = 1548852137
  5. unix := time.Unix(timestamp, 0).Format("2006-01-02 15:04:05")
  6. //字符串转时间
  7. formatTimeStr := "2017-04-11 13:33:37"
  8. strToTime, _ := time.Parse("2006-01-02 15:04:05", formatTimeStr)
  9. fmt.Println(format) //2019-01-30 21:00:53
  10. fmt.Println(unix)
  11. fmt.Println(strToTime) //2017-04-11 13:33:37 +0000 UTC
  12. }

1.8 复合数据类型

数组和切片(slice)之间的区别:

​ 数组:声明的时候必须指定长度var arr [10]int,值类型,但是在java里面数组是引用类型

​ Slice: 长度可变,不需要指定长度,引用类型

1. 数组

  1. //数组的声明
  2. func createArray() {
  3. var books [3]string
  4. books[0] = "java"
  5. books[1] = "python"
  6. books[2] = "golang"
  7. names := [3]string{"lisi", "zhansan", "hand"}
  8. scores := [...]int{89, 59, 30, 100} //根据后面的内容决定长度
  9. fmt.Println(books)
  10. fmt.Println(names)
  11. fmt.Println(scores)
  12. }
  13. //数组的相关操作
  14. func operateArray() {
  15. //数组长度
  16. scores := [...]int{89, 59, 30, 100}
  17. fmt.Println(len(scores))
  18. //数组遍历
  19. for i := 0; i < len(scores); i++ {
  20. fmt.Print(scores[i], "\t")
  21. }
  22. fmt.Println()
  23. for index, value := range scores {
  24. fmt.Print(index, "==", value, "\t")
  25. }
  26. }

2. slice

slice是一个比较复杂的数据结构,也就相当于Java里面集合的概念,是一个可变长的数据

  1. //最简单的一种声明方式
  2. func createSlice() {
  3. var args []int
  4. args = make([]int, 10)
  5. args[0] = 1
  6. args[1] = 2
  7. args[2] = 3
  8. args[3] = 4
  9. args[4] = 5
  10. for index, value := range args {
  11. fmt.Println(index, value)
  12. }
  13. }

通过数组定义一个切片

len 切片长度, 表示当前切片元素的个数

cap切片容量,表示切片可以容纳切片的个数,如果超出则报错

  1. func createSlice2() {
  2. arrays := [...]int{1, 2, 3, 4, 5}
  3. slice := arrays[1:4] //[2 3 4]
  4. fmt.Println(len(slice)) //3
  5. fmt.Println(cap(slice)) //4
  6. slice[1] = 10
  7. //这里可以解释下图
  8. fmt.Println(arrays) //[1 2 10 4 5]
  9. fmt.Println(slice) // [2 10 4]
  10. }

这里容量为什么是4?,如图

append&copy函数

当append超出原来容量的时候,会扩展原来的容量为原先的两倍

  1. //append
  2. func appendFunc() {
  3. slice := make([]int, 2, 4)
  4. slice[0] = 1
  5. slice[1] = 1
  6. slice = append(slice, 2)
  7. slice = append(slice, 3)
  8. slice = append(slice, 4)
  9. fmt.Println(len(slice)) //5
  10. fmt.Println(cap(slice)) //8
  11. }
  12. //copy函数的用法
  13. func copyFunc() {
  14. slice := make([]int, 2, 4)
  15. slice2 := make([]int, 2, 4)
  16. slice[0] = 1
  17. slice[1] = 1
  18. copy(slice2, slice) //相当于 slice2 := slice[:]
  19. fmt.Println(slice2) // [1 1]
  20. }

3. map

map 数据结构和java的HashMap类似。

  1. //创建一个map
  2. func createMap() {
  3. var product map[string]interface{} //声明
  4. product = make(map[string]interface{}) //初始化
  5. product["id"] = 1
  6. product["title"] = "口红"
  7. product["price"] = 199.33
  8. fmt.Println(product)
  9. }
  10. //遍历map
  11. func mapForEach() {
  12. var product map[string]interface{} //声明
  13. product = make(map[string]interface{}) //初始化
  14. product["id"] = 1
  15. product["title"] = "口红"
  16. product["price"] = 199.33
  17. for key, value := range product {
  18. fmt.Println(key, value)
  19. }
  20. }

1.9 golang面向对象

1. 结构体

go语言中的结构体和Java中的类很相似,包含属性,方法等内容。首字母大写对其他包可见,首字母小写只是对本包可见。

指针和值类型: 指针类型的方法可以修改属性的值,值类型的不可以修改,

  1. package main
  2. import "fmt"
  3. func main() {
  4. student := &Student{"zhansn", 24}
  5. fmt.Println(student.GetName())//zhansn
  6. student.SetName("lisi")
  7. fmt.Println(student.GetName()) //lisi
  8. }
  9. //对属性小写可以封装
  10. type Student struct {
  11. name string
  12. age int
  13. }
  14. //定义结构体的方法GetName和SetName
  15. func (this Student) GetName() string {
  16. return this.name
  17. }
  18. //这里使用指针可以改变属性的内容
  19. func (this *Student) SetName(name string) {
  20. this.name = name
  21. }

2. 继承

在go语言中结构体和结构体没有继承,而是通过组合的方式来获取其他结构体的方法。此时的Student可以使用Person的所有属性和方法,无论是否封装。

  1. package main
  2. import "fmt"
  3. func main() {
  4. student := &Student{}
  5. fmt.Println(student.GetName()) // ""
  6. student.SetName("lisi")
  7. fmt.Println(student.GetName()) //lisi
  8. }
  9. //对属性小写可以封装
  10. type Student struct {
  11. Person
  12. }
  13. type Person struct {
  14. name string
  15. age int
  16. }
  17. //定义类型的方法
  18. func (this Person) GetName() string {
  19. return this.name
  20. }
  21. //这里使用指针可以改变属性的内容
  22. func (this *Person) SetName(name string) {
  23. this.name = name
  24. }

3. 接口

golang接口中没有变量,只有方法。

对于java中的多态描述:重载和重写两种多态。但是在golang中无法对方法进行重载,因为golang是一门面向函数编程的语言。所以golang可以通过重写来实现多态,而且是接口和子类之间的重写。

  1. package main
  2. import "fmt"
  3. func main() {
  4. ben := &Ben{"benchi"}
  5. ao := &Ao{"aodi"}
  6. ToString(ben)
  7. ToString(ao)
  8. }
  9. type Car interface {
  10. GetName() string
  11. SetName(name string)
  12. }
  13. func ToString(car Car) {
  14. fmt.Println(car.GetName())
  15. }
  16. type Ben struct {
  17. name string
  18. }
  19. func (ben Ben) GetName() string {
  20. return ben.name
  21. }
  22. func (ben *Ben) SetName(name string) {
  23. ben.name = name
  24. }
  25. type Ao struct {
  26. name string
  27. }
  28. func (this Ao) GetName() string {
  29. return this.name
  30. }
  31. func (this *Ao) SetName(name string) {
  32. this.name = name
  33. }

4. 类型断言

golang 类型断言和java中的instanceof 关键字相似,但是又比这个关键字高级,好用,实现方式val.(T)

  1. func main() {
  2. var x interface{}
  3. x = 4
  4. if y, ok := x.(int); ok {
  5. fmt.Println(y)
  6. }
  7. }

断言接口子类

  1. package main
  2. import "fmt"
  3. func main() {
  4. ben := Ben{"benchi"}
  5. ao := Ao{"aodi"}
  6. ToString(ben)
  7. ToString(ao)
  8. }
  9. type Car interface {
  10. GetName() string
  11. }
  12. func ToString(car Car) {
  13. if ben, ok := car.(Ben); ok {
  14. fmt.Println(ben.GetName())
  15. } else if ao, ok := car.(Ao); ok {
  16. fmt.Println(ao.GetName())
  17. } else {
  18. fmt.Println("other type")
  19. }
  20. }
  21. type Ben struct {
  22. name string
  23. }
  24. func (ben Ben) GetName() string {
  25. return ben.name
  26. }
  27. type Ao struct {
  28. name string
  29. }
  30. func (this Ao) GetName() string {
  31. return this.name
  32. }

如下代码,有什么问题呢?此时我们使用指针类型是实现了接口notify的方法,那么在SendNotify(u notify)中我们必须使用子类的指针作为参数传递到该函数,如果我们使用值类型实现接口notify的方法,例如func (this user) Notify()这样既可以使用指针也可以使用值传递参数。

  1. package main
  2. import "fmt"
  3. func main() {
  4. u := &user{"hello"} //此时必须传递指针参数
  5. SendNotify(u)
  6. }
  7. type notify interface {
  8. Notify()
  9. }
  10. type user struct {
  11. name string
  12. }
  13. //指针实现接口
  14. func (this *user) Notify() {
  15. fmt.Println(this.name)
  16. }
  17. func SendNotify(u notify) {
  18. u.Notify()
  19. }

这是为什么呢?

对于一个方法method(param T) 可以接受值类型指针类型的参数,method(param *T) 仅仅可以接受指针类型的参数。

5. 闭包

java中有函数式编程,集合框架中有一个消费型函数forEach,我们在golang中通过闭包实现该函数

  1. package main
  2. import "fmt"
  3. func main() {
  4. data := []int{1,2,3,4,5}
  5. forEach(data, func(index int, value interface{}) {
  6. fmt.Println(index, value)
  7. })
  8. }
  9. func forEach(data []int, f func(int, interface{})) {
  10. for index, value := range data {
  11. f(index, value)
  12. }
  13. }

2. golang 杂项

2.0 defer

defer会在函数或者方法结束前被调用,和Java中finally相似

  1. func main() {
  2. /**
  3. first
  4. hello world
  5. defer is called
  6. */
  7. say()
  8. }
  9. func say() {
  10. fmt.Println("first")
  11. defer fmt.Println("defer is called")
  12. fmt.Println("hello world")
  13. }
  14. //由于return了,所以return后面的语句不会被执行
  15. func say2() {
  16. fmt.Println("first")
  17. return
  18. defer fmt.Println("defer is called")
  19. fmt.Println("hello world")
  20. }

defer使用场景:错误处理,关闭资源,释放锁,后续会见到这些使用操作

2.1 错误处理

这里诉说的错误处理和Java中的异常处理一样,在java语言中错误处理一般都是try...catch…finally,而在golang语言中通过三个关键字对错误尽心处理:(defer recover) panic

  1. defer+recover来捕获异常
  1. func catchError() {
  2. defer func() {
  3. err := recover()
  4. if err != nil {
  5. fmt.Println("出现异常", err)
  6. }
  7. }()
  8. a := 10
  9. b := 0
  10. x := a / b
  11. fmt.Println(x)
  12. }
  1. 自定义异常
  1. func catchError() {
  2. //在这里捕获处理,如果不进行捕获,则程序会崩溃
  3. defer func() {
  4. err := recover()
  5. if err != nil {
  6. fmt.Println("出现异常", err)
  7. }
  8. }()
  9. err := selfError()
  10. //向外抛出异常
  11. panic(err)
  12. }
  13. func selfError() error {
  14. return errors.New("自定义异常")
  15. }

2.2 日志

  1. package main
  2. import "log"
  3. func main() {
  4. // info:2019/02/04 16:47:25 LoggerDemo.go:6: message
  5. log.Println("message")
  6. }
  7. func init() {
  8. log.SetPrefix("info:")
  9. log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
  10. }
  1. func main() {
  2. log.Println("message")
  3. //Fatalln执行之后调用:os.Exit(1), 退出程序,后续程序不再执行
  4. log.Fatalln("打印日志,程序退出")
  5. fmt.Println("还会执行吗")
  6. }

定制日志记录器

  1. package logger
  2. import (
  3. "log"
  4. "os"
  5. "io"
  6. )
  7. var (
  8. Debug *log.Logger //仅仅输出到控制台
  9. Info *log.Logger
  10. Warning *log.Logger
  11. Error *log.Logger
  12. )
  13. const (
  14. logFlag = log.LstdFlags | log.Lshortfile
  15. )
  16. func init() {
  17. file, error := os.OpenFile("info.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  18. if error != nil {
  19. panic(error)
  20. }
  21. Debug = log.New(os.Stdout, "debug:", logFlag)
  22. Info = log.New(io.MultiWriter(file, os.Stdout), "info:", logFlag)
  23. Warning = log.New(os.Stdout, "waring:", logFlag)
  24. Error = log.New(io.MultiWriter(file, os.Stderr), "error:", logFlag)
  25. }

测试

  1. package main
  2. import "logger"
  3. func main() {
  4. logger.Debug.Println("debug")
  5. logger.Info.Println("create a info log")
  6. logger.Error.Println("create a errr log")
  7. }

2.3 IO流

  1. package main
  2. import (
  3. "os"
  4. "fmt"
  5. "bufio"
  6. "io"
  7. "io/ioutil"
  8. )
  9. func openFile() {
  10. file, err := os.Open("info.log")
  11. if err != nil {
  12. fmt.Println("文件错误", err)
  13. }
  14. defer file.Close()
  15. reader := bufio.NewReader(file)
  16. for {
  17. str, err := reader.ReadString('\n')
  18. if err == io.EOF { //表示读取完毕
  19. break
  20. }
  21. fmt.Print(str)
  22. }
  23. }
  24. //读取内容到内存中
  25. func openFile2() {
  26. data, err := ioutil.ReadFile("info.log")
  27. if err != nil {
  28. }
  29. fmt.Print(string(data))
  30. }
  31. func writeFile() {
  32. file, err := os.OpenFile("hello.txt", os.O_WRONLY| os.O_CREATE | os.O_APPEND, 0666)
  33. if err != nil {
  34. fmt.Println("创建文件错误")
  35. return
  36. }
  37. defer file.Close()
  38. writer := bufio.NewWriter(file)
  39. for i := 0; i < 5; i++ {
  40. writer.WriteString("写入数据:\n")
  41. }
  42. writer.Flush() //将缓冲区内容写入到文件中
  43. }
  44. //判断文件是否存在
  45. func IsExist() {
  46. _, e := os.Stat("info2.log")
  47. if e != nil {
  48. exist := os.IsNotExist(e)
  49. fmt.Println(exist)
  50. }
  51. }

2.5 json

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "time"
  6. )
  7. type Book struct {
  8. Title string
  9. Author string
  10. Publish time.Time
  11. }
  12. //序列化map
  13. func serializeMap() {
  14. student := make(map[string]interface{})
  15. student["name"] = "闰土"
  16. student["age"] = 20
  17. student["class"] = "大一"
  18. bytes, err := json.Marshal(student)
  19. if err != nil {
  20. fmt.Println("序列化错误")
  21. }
  22. fmt.Println(string(bytes)) //{"age":20,"class":"大一","name":"闰土"}
  23. }
  24. //序列化结构体
  25. func serializeStruct() {
  26. book := Book{"青春","itcloud", time.Now()}
  27. bytes, _ := json.Marshal(book)
  28. fmt.Println(string(bytes)) // {"Title":"青春","Author":"itcloud","Publish":"2019-02-05T11:14:51.094709+08:00"}
  29. }
  30. func deserializeMap() {
  31. var student map[string]interface{}
  32. data := `{"age":20,"class":"大一","name":"闰土"}`
  33. err := json.Unmarshal([]byte(data), &student)
  34. if err != nil {}
  35. fmt.Println(student)
  36. }
  37. func deserializeStruct() {
  38. var book Book
  39. bookStr := `{"Title":"青春","Author":"itcloud","Publish":"2019-02-05T11:14:51.094709+08:00"}`
  40. json.Unmarshal([]byte(bookStr), &book)
  41. fmt.Println(book)
  42. }

2.6 网络编程

1. TCP

客户端

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "net"
  6. "os"
  7. )
  8. func main() {
  9. conn, _ := net.Dial("tcp", "127.0.0.1:8088")
  10. reader := bufio.NewReader(os.Stdin)
  11. line, _ := reader.ReadString('\n')
  12. n, _ := conn.Write([]byte(line))
  13. fmt.Println(n)
  14. }

服务端

  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. )
  6. func main() {
  7. listener, err := net.Listen("tcp", "127.0.0.1:8088")
  8. if flag := Checkout(err, "监听开启错误"); !flag {
  9. return
  10. }
  11. defer listener.Close()
  12. for {
  13. fmt.Println("等待客户端建立连接...")
  14. conn, err := listener.Accept()
  15. if flag := Checkout(err, "打开连接失败"); flag {
  16. fmt.Printf("conn= %v, ip = %v\n", conn, conn.RemoteAddr().String())
  17. }
  18. go process(conn)
  19. }
  20. }
  21. func process (conn net.Conn) {
  22. defer conn.Close()
  23. for {
  24. buf := make([]byte, 1024)
  25. readLen, err := conn.Read(buf)
  26. if flag := Checkout(err, "读取失败"); !flag {
  27. return
  28. }
  29. fmt.Println(string(buf[:readLen]))
  30. }
  31. }
  32. func Checkout(err error, msg string) bool {
  33. if err != nil {
  34. fmt.Println(msg, err)
  35. return false
  36. }
  37. return true
  38. }

2. http

  1. func main() {
  2. http.HandleFunc("/echo", echo)
  3. http.ListenAndServe(":8080", nil)
  4. }
  5. func echo(w http.ResponseWriter, r *http.Request) {
  6. body, err := ioutil.ReadAll(r.Body)
  7. if err != nil {
  8. w.Write([]byte("get body error"))
  9. return
  10. }
  11. strlen, err := w.Write(body)
  12. if err != nil && strlen != len(body) {
  13. w.Write([]byte("write a error"))
  14. }
  15. }
  1. package main
  2. import (
  3. "net/http"
  4. "time"
  5. )
  6. //自定义handler
  7. func main() {
  8. myHandler := &SelfHandle{format: time.RFC1123}
  9. http.Handle("/time", myHandler)
  10. http.ListenAndServe(":8080", nil)
  11. }
  12. type SelfHandle struct {
  13. format string
  14. }
  15. func (h *SelfHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  16. forTime := time.Now().Format(h.format)
  17. w.Write([]byte("time is " + forTime))
  18. }

多路复用处理器

  1. package main
  2. import "net/http"
  3. //多路复用处理器
  4. func main() {
  5. mux := http.NewServeMux()
  6. mux.HandleFunc("/hello", hello)
  7. mux.HandleFunc("/world", world)
  8. server := &http.Server{Addr: ":8080", Handler: mux}
  9. server.ListenAndServe()
  10. }
  11. func hello(w http.ResponseWriter, r *http.Request) {
  12. w.Write([]byte("hello"))
  13. }
  14. func world(w http.ResponseWriter, r *http.Request) {
  15. w.Write([]byte("word"))
  16. }

golang学习总结的更多相关文章

  1. golang学习之beego框架配合easyui实现增删改查及图片上传

    golang学习之beego框架配合easyui实现增删改查及图片上传 demo目录: upload文件夹主要放置上传的头像文件,main是主文件,所有效果如下: 主页面: 具体代码: <!DO ...

  2. Golang学习 - 学习资源列表

    Golang 学习资源: <Go 语言圣经(中文版)>  - 书籍 http://shinley.com/index.html <学习 Go 语言> - 书籍 http://w ...

  3. Golang学习:sublime text3配置golang环境

    最近导师让学习golang, 然后我就找了些有关golang的学习视频和网站. 昨天在电脑上下载了go tools, 之后在sublime上配置了golang的运行环境.By the way, 我的电 ...

  4. golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题

    golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题 下面这个程序运行的能num结果是什么? package main import ( "fmt" " ...

  5. golang学习笔记19 用Golang实现以太坊代币转账

    golang学习笔记19 用Golang实现以太坊代币转账 在以太坊区块链中,我们称代币为Token,是以太坊区块链中每个人都可以任意发行的数字资产.并且它必须是遵循erc20标准的,至于erc20标 ...

  6. golang学习笔记18 用go语言编写移动端sdk和app开发gomobile

    golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...

  7. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

  8. golang学习笔记16 beego orm 数据库操作

    golang学习笔记16 beego orm 数据库操作 beego ORM 是一个强大的 Go 语言 ORM 框架.她的灵感主要来自 Django ORM 和 SQLAlchemy. 目前该框架仍处 ...

  9. golang学习笔记14 golang substring 截取字符串

    golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...

  10. golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换

    golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...

随机推荐

  1. 倒计时特效的CountAnimationLabel

    倒计时特效的CountAnimationLabel 效果: 源码: CountAnimationLabel.h 与 CountAnimationLabel.m // // CountAnimation ...

  2. MSDN版、OEM版、RTM版、VOL版等的区别

    我们常常听说操作系统的MSDN版.OEM版.RTM版.VOL版等等,它们到底是什么意思,有什么不同呢? (一)MSDN (Microsoft Developer Network)版MSDN软件是微软公 ...

  3. Linux ping命令详解

    Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性 基于IMCP协议 常见命令参数 -q 不显示任何传送封包的信息,只显示最后的结果 -n 只输出数值 -R 记录路由过程 ...

  4. Linxu下 expect的安装与使用

    expect学习 1.什么是except        Expect是基于Tcl的一个相对简单的免费脚本文件语言工具,用于实现自动和交互式程序进行通信            is a software ...

  5. Android启动外部应用的方法

    1.根据package的名称获取应用的Launch Intent Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage ...

  6. js获取鼠标坐标位置兼容多个浏览器

    这个是IE 11 下兼容下视图测试时可用. $(window).bind('beforeunload', function (event) { var _this = this; var x = ev ...

  7. codeforces 407C Curious Array

    codeforces 407C Curious Array UPD: 我觉得这个做法比较好理解啊 参考题解:https://www.cnblogs.com/ChopsticksAN/p/4908377 ...

  8. python接口测试:自动保存cookies

    接口测试中遇到上一个请求返回响应包含cookie(如下图登录请求的响应结果).需将cookies保存下来,后续请求自动带入,否则会提示未登录. python requests的cookie类型是< ...

  9. VNC Viewer

    首先需要明确,什么事VNC , Virtual Network Computing ,VNC允许Linux系统可以类似实现像Windows中的远程桌面访问那样访问Linux桌面. 首先试试服务器装了V ...

  10. python的*args和**kwargs基础用法

    *args表示任何多个无名参数,它是一个tuple **kwargs:传入的字典,就如:a=1,传入键值,默认就传入到**kwargs中,如下面代码: class FOO: def __init__( ...