经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
GO 语言快速学习 | PHP转GO笔记
来源:cnblogs  作者:smallsha  时间:2021/5/31 9:12:16  对本文有异议

web框架

流行度排行

https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#popularity

beego

https://beego.me/products

echo

https://echo.labstack.com/

gin
go社区文档

https://learnku.com/docs/gin-gonic/2019

看云gin文档

https://www.kancloud.cn/shuangdeyu/gin_book/949418

gin快速使用

https://www.jianshu.com/p/98965b3ff638

gin-admin-vue

https://www.gin-vue-admin.com/docs/gorm

官网

https://golang.org/dl/

中文官网

https://go-zh.org/pkg/

go常用库

https://github.com/jobbole/awesome-go-cn

查看版本号

go version

查看env

go env

拉不下来包

  1. export GOPATH=/usr/local/go/bin
  2. export GOPROXY=https://goproxy.io
  3. export PATH=$PATH:$GOPATH
  4. export GO111MODULE=on

开启module

go env -w GO111MODULE=on

设置代理

go env -w GOPROXY=https://goproxy.io,direct

微服务框架

go-kit

go micro

go-zero

常用网址

go基础知识

go基础知识v1

go基础知识v2---micro

菜鸟GO

文档和技术论坛

gomod 详细使用

go官网库

go官方pkg中文

github对pgk的使用例子

go mod使用

image

基本数据类型

image

字符串操作

image

本地gorm struct生成

https://github.com/xxjwxc/gormt.git

本地struct生成

https://github.com/hantmac/fuckdb.git

  1. 1 使用docker-composer方式启动
  2. 2 遇到docker容器不能链接本地mysql的时候
  3. 在本地mysql
  4. GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
  5. FLUSH PRIVILEGES

struct 生成

go get -u github.com/gohouse/converter

  1. err := converter.NewTable2Struct().
  2. SavePath("./model.go").
  3. Dsn("root:root@tcp(127.0.0.1:3306)/foroo_beta_shopify?charset=utf8").
  4. TagKey("db").
  5. EnableJsonTag(true).
  6. Table("fr_store").
  7. Run()
  8. fmt.Println(err)
  9. return

基础

变量或者方法使用小写相当于protect 首字母大写 相当于public

使用+来拼接字符串

变量声明 var age int;

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

可以将 var f string = "Runoob" 简写为 f := "Runoob":

函数外的每个语句都必须以关键字开始(var、const、func等)

:=不能使用在函数外。

_多用于占位,表示忽略值。import _ "./hello" 用_占位只会执行导入包内的init,其他方法都不能调用

iota是go语言的常量计数器,只能在常量的表达式中使用

strconv.Itoa(97) 将一个数字转成字符串类型 string(97)go自带的会把数字转换成对应的ascii码

  1. const (
  2. n1 = iota //0
  3. n2 //1
  4. n3 //2
  5. n4 //3
  6. )

map、slice、chan、指针、interface默认以引用的方式传递。

互斥锁 var lock sync.Mutex

  1. var x int64
  2. var wg sync.WaitGroup
  3. var lock sync.Mutex
  4. func add() {
  5. for i := 0; i < 5000; i++ {
  6. lock.Lock() // 加锁
  7. x = x + 1
  8. lock.Unlock() // 解锁
  9. }
  10. wg.Done()
  11. }
  12. func main() {
  13. wg.Add(2)
  14. go add()
  15. go add()
  16. wg.Wait()
  17. fmt.Println(x)
  18. }

读写互斥锁 需要注意的是读写锁非常适合读多写少的场景,如果读和写的操作差别不大,读写锁的优势就发挥不出来。

  1. var (
  2. x int64
  3. wg sync.WaitGroup
  4. lock sync.Mutex
  5. rwlock sync.RWMutex
  6. )
  7. func write() {
  8. // lock.Lock() // 加互斥锁
  9. rwlock.Lock() // 加写锁
  10. x = x + 1
  11. time.Sleep(10 * time.Millisecond) // 假设读操作耗时10毫秒
  12. rwlock.Unlock() // 解写锁
  13. // lock.Unlock() // 解互斥锁
  14. wg.Done()
  15. }
  16. func read() {
  17. // lock.Lock() // 加互斥锁
  18. rwlock.RLock() // 加读锁
  19. time.Sleep(time.Millisecond) // 假设读操作耗时1毫秒
  20. rwlock.RUnlock() // 解读锁
  21. // lock.Unlock() // 解互斥锁
  22. wg.Done()
  23. }
  24. func main() {
  25. start := time.Now()
  26. for i := 0; i < 10; i++ {
  27. wg.Add(1)
  28. go write()
  29. }
  30. for i := 0; i < 1000; i++ {
  31. wg.Add(1)
  32. go read()
  33. }
  34. wg.Wait()
  35. end := time.Now()
  36. fmt.Println(end.Sub(start))
  37. }

sync.Once其实内部包含一个互斥锁和一个布尔值,互斥锁保证布尔值和数据的安全,而布尔值用来记录初始化是否完成。这样设计就能保证初始化操作的时候是并发安全的并且初始化操作也不会被执行多次。

  1. var icons map[string]image.Image
  2. var loadIconsOnce sync.Once
  3. func loadIcons() {
  4. icons = map[string]image.Image{
  5. "left": loadIcon("left.png"),
  6. "up": loadIcon("up.png"),
  7. "right": loadIcon("right.png"),
  8. "down": loadIcon("down.png"),
  9. }
  10. }
  11. // Icon 是并发安全的
  12. func Icon(name string) image.Image {
  13. loadIconsOnce.Do(loadIcons)
  14. return icons[name]
  15. }

goroutine高并发下 操作map 要用 sync.Map 来操作

  1. //sync.Map内置了诸如Store、Load、LoadOrStore、Delete、Range等操作方法
  2. var m = sync.Map{}
  3. func main() {
  4. wg := sync.WaitGroup{}
  5. for i := 0; i < 20; i++ {
  6. wg.Add(1)
  7. go func(n int) {
  8. key := strconv.Itoa(n)
  9. m.Store(key, n)
  10. value, _ := m.Load(key)
  11. fmt.Printf("k=:%v,v:=%v\n", key, value)
  12. wg.Done()
  13. }(i)
  14. }
  15. wg.Wait()
  16. }

代码中的加锁操作因为涉及内核态的上下文切换会比较耗时、代价比较高。针对基本数据类型我们还可以使用原子操作来保证并发安全,因为原子操作是Go语言提供的方法它在用户态就可以完成,因此性能比加锁操作更好。Go语言中原子操作由内置的标准库sync/atomic提供。

  1. // 原子操作版加函数
  2. func atomicAdd() {
  3. atomic.AddInt64(&x, 1)
  4. wg.Done()
  5. }

make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身

变量之间使用引用地址直接可以改变

  1. package main
  2. func swap(a, b *int) {
  3. var temp int
  4. temp = *a
  5. *a = *b
  6. *b = temp
  7. }
  8. func main() {
  9. var a, b = 1, 2
  10. swap(&a, &b)
  11. fmt.Println(a)
  12. fmt.Println(b)
  13. }
  14. //指针小案例
  15. var a int
  16. fmt.Println(&a)
  17. var p *int
  18. p = &a
  19. *p = 20
  20. fmt.Println(a)

在参数赋值时可以不用用一个一个的赋值,可以直接传递一个数组或者切片,特别注意的是在参数后加上“…”即可

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func test(s string, n ...int) string {
  6. var x int
  7. for _, i := range n {
  8. x += i
  9. }
  10. return fmt.Sprintf(s, x)
  11. }
  12. func main() {
  13. s := []int{1, 2, 3}
  14. res := test("sum: %d", s...) // slice... 展开slice
  15. println(res)
  16. }

"_"标识符,用来忽略函数的某个返回值

没有参数的 return 语句返回各个返回变量的当前值。这种用法被称作“裸”返回。

  1. func add(a, b int) (c int) {
  2. c = a + b
  3. return
  4. }
  5. func calc(a, b int) (sum int, avg int) {
  6. sum = a + b
  7. avg = (a + b) / 2
  8. return
  9. }
  10. func main() {
  11. var a, b int = 1, 2
  12. c := add(a, b)
  13. sum, avg := calc(a, b)
  14. fmt.Println(a, b, c, sum, avg)
  15. }

命名返回参数允许 defer 延迟调用通过闭包读取和修改。

defer 是先进后出

  1. package main
  2. func add(x, y int) (z int) {
  3. defer func() {
  4. z += 100
  5. }()
  6. z = x + y
  7. return
  8. }
  9. func main() {
  10. println(add(1, 2))
  11. }

定义一维数组

  1. var a [5]int = [5]int{1,2,5,6,7}
  2. var a = [...]int{1,2,3,5,6}
  3. d := [...]struct {
  4. name string
  5. age uint8
  6. }{
  7. {"user1", 10}, // 可省略元素类型。
  8. {"user2", 20}, // 别忘了最后一行的逗号。
  9. }

定义二维数组 第 2 纬度不能用 "..."

  1. var b [3][2]int = [3][2]int{{1,2},{3,4},{5,6}}
  2. var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

定义slice

  1. 全局:
  2. var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  3. var slice0 []int = arr[start:end]
  4. var slice1 []int = arr[:end]
  5. var slice2 []int = arr[start:]
  6. var slice3 []int = arr[:]
  7. var slice4 = arr[:len(arr)-1] //去掉切片的最后一个元素
  8. 局部:
  9. arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
  10. slice5 := arr[start:end]
  11. slice6 := arr[:end]
  12. slice7 := arr[start:]
  13. slice8 := arr[:]
  14. slice9 := arr[:len(arr)-1] //去掉切片的最后一个元素
  15. //通过make来创建切片
  16. var slice []type = make([]type, len)
  17. slice := make([]type, len)
  18. slice := make([]type, len, cap)

定义map

  1. scoreMap := make(map[string]int)
  2. scoreMap["张三"] = 90
  3. scoreMap["小明"] = 100
  4. // 如果key存在ok为true,v为对应的值;不存在ok为false,v为值类型的零值
  5. v, ok := scoreMap["张三"]
  6. if ok {
  7. fmt.Println(v)
  8. } else {
  9. fmt.Println("查无此人")
  10. }
  11. //使用delete()函数删除键值对
  12. delete(scoreMap, "小明")//将小明:100从map中删除

数组按照下标排序输出

  1. tetcc := make(map[int]string,5)
  2. tetcc[1] = "smallsha"
  3. tetcc[5] = "smallsha1"
  4. tetcc[3] = "smallsha2"
  5. sli := []int{}
  6. for i := range tetcc {
  7. sli = append(sli,i)
  8. }
  9. sort.Ints(sli)
  10. for i := 0; i < len(tetcc); i++ {
  11. fmt.Println("内容",tetcc[sli[i]])
  12. }
  13. fmt.Printf("%#v\n", sli)
  14. return

if判断

  1. if test2 :=19; test2> 20 {
  2. fmt.Println("test11212121212")
  3. }else if test2 < 20 {
  4. fmt.Println("test1111")
  5. }

switch使用

  1. test3 := 80
  2. switch test3 {
  3. case 80:
  4. fmt.Println("1")
  5. fallthrough //可以使用fallthrough强制执行后面的case代码。
  6. case 90:
  7. fmt.Println("2")
  8. case 100:
  9. fmt.Println("3")
  10. default:
  11. fmt.Println("default")
  12. }

多个参数调用

  1. func test(s string, n ...int) string {
  2. var x int
  3. for _, i := range n {
  4. x += i
  5. }
  6. return fmt.Sprintf(s, x)
  7. }
  8. s := []int{1, 2, 3}
  9. res := test("sum: %d", s...) // slice... 展开slice
  10. println(res)

闭包使用

  1. func a() func() int {
  2. i := 0
  3. b := func() int{
  4. i++
  5. fmt.Println(i)
  6. return i
  7. }
  8. return b
  9. }
  10. ccccc := a()
  11. ccccc()
  12. ccccc()
  13. return

关键字 defer 用于注册延迟调用。

这些调用直到 return 前才被执。因此,可以用来做资源清理。

多个defer语句,按先进后出的方式执行

惯例是:导致关键流程出现不可修复性错误的使用 panic,其他使用 error。

  1. func main() {
  2. test()
  3. }
  4. func test() {
  5. defer func() {
  6. if err := recover(); err != nil {
  7. println(err.(string)) // 将 interface{} 转型为具体类型。
  8. }
  9. }()
  10. panic("panic error!")
  11. }

表达式

  1. package main
  2. import "fmt"
  3. type User struct {
  4. id int
  5. name string
  6. }
  7. func (self *User) Test() {
  8. fmt.Printf("%p, %v\n", self, self)
  9. }
  10. func main() {
  11. u := User{1, "Tom"}
  12. u.Test()
  13. mValue := u.Test
  14. mValue() // 隐式传递 receiver
  15. mExpression := (*User).Test
  16. mExpression(&u) // 显式传递 receiver
  17. }

定义error
http://www.topgoer.com/方法/自定义error.html

  1. //返回异常
  2. package main
  3. import (
  4. "errors"
  5. "fmt"
  6. )
  7. func getCircleArea(radius float32) (area float32, err error) {
  8. if radius < 0 {
  9. // 构建个异常对象
  10. err = errors.New("半径不能为负")
  11. return
  12. }
  13. area = 3.14 * radius * radius
  14. return
  15. }
  16. func main() {
  17. area, err := getCircleArea(-5)
  18. if err != nil {
  19. fmt.Println(err)
  20. } else {
  21. fmt.Println(area)
  22. }
  23. }
  24. //系统抛异常
  25. package main
  26. import "fmt"
  27. func test01() {
  28. a := [5]int{0, 1, 2, 3, 4}
  29. a[1] = 123
  30. fmt.Println(a)
  31. //a[10] = 11
  32. index := 10
  33. a[index] = 10
  34. fmt.Println(a)
  35. }
  36. func getCircleArea(radius float32) (area float32) {
  37. if radius < 0 {
  38. // 自己抛
  39. panic("半径不能为负")
  40. }
  41. return 3.14 * radius * radius
  42. }
  43. func test02() {
  44. getCircleArea(-5)
  45. }
  46. //
  47. func test03() {
  48. // 延时执行匿名函数
  49. // 延时到何时?(1)程序正常结束 (2)发生异常时
  50. defer func() {
  51. // recover() 复活 恢复
  52. // 会返回程序为什么挂了
  53. if err := recover(); err != nil {
  54. fmt.Println(err)
  55. }
  56. }()
  57. getCircleArea(-5)
  58. fmt.Println("这里有没有执行")
  59. }
  60. func test04() {
  61. test03()
  62. fmt.Println("test04")
  63. }
  64. func main() {
  65. test04()
  66. }
  67. //自定义error
  68. package main
  69. import (
  70. "fmt"
  71. "os"
  72. "time"
  73. )
  74. type PathError struct {
  75. path string
  76. op string
  77. createTime string
  78. message string
  79. }
  80. func (p *PathError) Error() string {
  81. return fmt.Sprintf("path=%s \nop=%s \ncreateTime=%s \nmessage=%s", p.path,
  82. p.op, p.createTime, p.message)
  83. }
  84. func Open(filename string) error {
  85. file, err := os.Open(filename)
  86. if err != nil {
  87. return &PathError{
  88. path: filename,
  89. op: "read",
  90. message: err.Error(),
  91. createTime: fmt.Sprintf("%v", time.Now()),
  92. }
  93. }
  94. defer file.Close()
  95. return nil
  96. }
  97. func main() {
  98. err := Open("/Users/5lmh/Desktop/go/src/test.txt")
  99. switch v := err.(type) {
  100. case *PathError:
  101. fmt.Println("get path error,", v)
  102. default:
  103. }
  104. }

interface 应用

  1. // 空接口作为函数参数
  2. func show(a interface{}) {
  3. fmt.Printf("type:%T value:%v\n", a, a)
  4. }
  5. // 空接口作为map值
  6. var studentInfo = make(map[string]interface{})
  7. studentInfo["name"] = "李白"
  8. studentInfo["age"] = 18
  9. studentInfo["married"] = false
  10. fmt.Println(studentInfo)

go调度 sync.WaitGroup

  1. var wg sync.WaitGroup
  2. func hello(i int) {
  3. defer wg.Done() // goroutine结束就登记-1
  4. fmt.Println("Hello Goroutine!", i)
  5. }
  6. func main() {
  7. for i := 0; i < 10; i++ {
  8. wg.Add(1) // 启动一个goroutine就登记+1
  9. go hello(i)
  10. }
  11. wg.Wait() // 等待所有登记的goroutine都结束
  12. }

go runtime.Gosched()

  1. //让出CPU时间片,重新等待安排任务(大概意思就是本来计划的好好的周末出去烧烤,但是你妈让你去相亲,两种情况第一就是你相亲速度非常快,见面就黄不耽误你继续烧烤,第二种情况就是你相亲速度特别慢,见面就是你侬我侬的,耽误了烧烤,但是还馋就是耽误了烧烤你还得去烧烤)
  2. package main
  3. import (
  4. "fmt"
  5. "runtime"
  6. )
  7. func main() {
  8. go func(s string) {
  9. for i := 0; i < 2; i++ {
  10. fmt.Println(s)
  11. }
  12. }("world")
  13. // 主协程
  14. for i := 0; i < 2; i++ {
  15. // 切一下,再次分配任务
  16. runtime.Gosched()
  17. fmt.Println("hello")
  18. }
  19. }

runtime.Goexit()

  1. //退出当前协程(一边烧烤一边相亲,突然发现相亲对象太丑影响烧烤,果断让她滚蛋,然后也就没有然后了)
  2. package main
  3. import (
  4. "fmt"
  5. "runtime"
  6. )
  7. func main() {
  8. go func() {
  9. defer fmt.Println("A.defer")
  10. func() {
  11. defer fmt.Println("B.defer")
  12. // 结束协程
  13. runtime.Goexit()
  14. defer fmt.Println("C.defer")
  15. fmt.Println("B")
  16. }()
  17. fmt.Println("A")
  18. }()
  19. for {
  20. }
  21. }

runtime.GOMAXPROCS

  1. //Go1.5版本之后,默认使用全部的CPU逻辑核心数
  2. ///两个任务只有一个逻辑核心,此时是做完一个任务再做另一个任务。 将逻辑核心数设为2,此时两个任务并行执行,代码如下。
  3. func a() {
  4. for i := 1; i < 10; i++ {
  5. fmt.Println("A:", i)
  6. }
  7. }
  8. func b() {
  9. for i := 1; i < 10; i++ {
  10. fmt.Println("B:", i)
  11. }
  12. }
  13. func main() {
  14. runtime.GOMAXPROCS(2)
  15. go a()
  16. go b()
  17. time.Sleep(time.Second)
  18. }

通道

1.对一个关闭的通道再发送值就会导致panic。

2.对一个关闭的通道进行接收会一直获取值直到通道为空。

3.对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值。

4.关闭一个已经关闭的通道会导致panic。

5.chan<- int是一个只能发送的通道,可以发送但是不能接收;

6 <-chan int是一个只能接收的通道,可以接收但是不能发送。

  1. func counter(out chan<- int) {
  2. for i := 0; i < 100; i++ {
  3. out <- i
  4. }
  5. close(out)
  6. }
  7. func squarer(out chan<- int, in <-chan int) {
  8. for i := range in {
  9. out <- i * i
  10. }
  11. close(out)
  12. }
  13. func printer(in <-chan int) {
  14. for i := range in {
  15. fmt.Println(i)
  16. }
  17. }
  18. func main() {
  19. ch1 := make(chan int)
  20. ch2 := make(chan int)
  21. go counter(ch1)
  22. go squarer(ch2, ch1)
  23. printer(ch2)
  24. }

通道使用案例

  1. type Job struct {
  2. Id int
  3. RandNum int
  4. }
  5. type Result struct {
  6. job *Job
  7. sum int
  8. }
  9. func createPool(num int, jobChan chan *Job,resultChan chan *Result) {
  10. for i := 0; i < num; i++ {
  11. go func(jobChan chan *Job,resultChan chan *Result) {
  12. for i2 := range jobChan {
  13. r_num := i2.RandNum
  14. var sum int
  15. for r_num !=0 {
  16. tmp := r_num % 10
  17. sum += tmp
  18. r_num /= 10
  19. }
  20. r := &Result{
  21. job: i2,
  22. sum: sum,
  23. }
  24. resultChan <- r
  25. }
  26. }(jobChan,resultChan)
  27. }
  28. }
  29. func main() {
  30. flag.Parse()
  31. jobChan := make(chan *Job, 128)
  32. resultChan := make(chan *Result, 128)
  33. createPool(64, jobChan, resultChan)
  34. // 4.开个打印的协程
  35. go func(resultChan chan *Result) {
  36. // 遍历结果管道打印
  37. for result := range resultChan {
  38. fmt.Printf("job id:%v randnum:%v result:%d\n", result.job.Id,
  39. result.job.RandNum, result.sum)
  40. }
  41. }(resultChan)
  42. var id int
  43. // 循环创建job,输入到管道
  44. for {
  45. id++
  46. // 生成随机数
  47. r_num := rand.Int()
  48. job := &Job{
  49. Id: id,
  50. RandNum: r_num,
  51. }
  52. jobChan <- job
  53. }
  54. return
  55. }

select 监听通道

  1. select {
  2. case <-chan1:
  3. // 如果chan1成功读到数据,则进行该case处理语句
  4. case chan2 <- 1:
  5. // 如果成功向chan2写入数据,则进行该case处理语句
  6. default:
  7. // 如果上面都没有成功,则进入default处理流程
  8. }

flag使用 和 os.args

  1. var name string
  2. var age int
  3. var married bool
  4. var delay time.Duration
  5. flag.StringVar(&name, "name", "张三", "姓名")
  6. flag.IntVar(&age, "age", 18, "年龄")
  7. flag.BoolVar(&married, "married", false, "婚否")
  8. flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")
  9. 或者使用
  10. name := flag.String("name", "张三", "姓名")
  11. age := flag.Int("age", 18, "年龄")
  12. married := flag.Bool("married", false, "婚否")
  13. delay := flag.Duration("d", 0, "时间间隔")
  14. //解析命令行参数
  15. flag.Parse()
  16. fmt.Println(name, age, married, delay)
  17. //返回命令行参数后的其他参数
  18. fmt.Println(flag.Args())
  19. //返回命令行参数后的其他参数个数
  20. fmt.Println(flag.NArg())
  21. //返回使用的命令行参数个数
  22. fmt.Println(flag.NFlag())
  23. //os.args
  24. if len(os.Args) > 0 {
  25. for index, arg := range os.Args {
  26. fmt.Printf("args[%d]=%v\n", index, arg)
  27. }
  28. }

Log文件

  1. logFile, err := os.OpenFile("./smallsha.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
  2. if err != nil {
  3. fmt.Println("open log file failed, err:", err)
  4. return
  5. }
  6. log.SetOutput(logFile) //设置日志文件写入
  7. log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
  8. log.SetPrefix("[smallsha]")
  9. log.Printf("%s","smallsha")
  10. log.Println("test")
  11. //log.Panic("test1")
  12. //log.Fatalln("test2")
  13. logger := log.New(os.Stdout, "<New>", log.Lshortfile|log.Ldate|log.Ltime)
  14. logger.Println("这是自定义的logger记录的日志。")

循环操作

  1. arr := [5]int{1,2,4,5,6,8}
  2. for i,num :=range arr {
  3. fmt.Println(i,num)
  4. }
  5. //while for 循环配合通道
  6. var (
  7. ch11 = make(chan int)
  8. ch12 = make(chan int)
  9. )
  10. go func() {
  11. for i := 0; i < 10; i++ {
  12. ch11 <- i
  13. }
  14. close(ch11)
  15. }()
  16. go func() {
  17. for {
  18. i, ok := <-ch11
  19. if !ok {
  20. break
  21. }
  22. ch12 <- i * i
  23. }
  24. close(ch12)
  25. }()
  26. for i := range ch12 {
  27. fmt.Println(i)
  28. }

指针

  1. const MAX int =3
  2. func main(){
  3. a :=[]int{1,3,5}
  4. var ptr [MAX]*int;
  5. for i = 0; i < MAX; i++ {
  6. ptr[i] = &a[i] /* 整数地址赋值给指针数组 */
  7. }
  8. for i = 0; i < MAX; i++ {
  9. fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
  10. }
  11. }

strconv 使用

  1. s3, _ := strconv.ParseBool("1")
  2. fmt.Printf("%# v\n", pretty.Formatter(s3))
  3. return
  4. //int 转 string
  5. s2 := 100
  6. i2 := strconv.Itoa(s2)
  7. fmt.Printf("%# v\n", pretty.Formatter(i2))
  8. return
  9. //string 转 int
  10. s1 := "100"
  11. i1, err := strconv.Atoi(s1)
  12. if err != nil {
  13. fmt.Println(err)
  14. return
  15. }
  16. fmt.Printf("%# v\n", pretty.Formatter(i1))
  17. return

template使用可以注册http

  1. package logic
  2. import (
  3. "fmt"
  4. "html/template"
  5. "net/http"
  6. )
  7. func init() {
  8. http.HandleFunc("/",sayHello)
  9. err := http.ListenAndServe(":9090", nil)
  10. if err != nil {
  11. fmt.Println(err)
  12. return
  13. }
  14. }
  15. type UserInfo struct {
  16. Name string
  17. Gender string
  18. Age int
  19. }
  20. func sayHello(w http.ResponseWriter,r *http.Request) {
  21. // 解析指定文件生成模板对象
  22. tmpl, err := template.ParseFiles("./hello.html")
  23. if err != nil {
  24. fmt.Println("create template failed, err:", err)
  25. return
  26. }
  27. // 利用给定数据渲染模板,并将结果写入w
  28. user := UserInfo{
  29. Name: "枯藤",
  30. Gender: "男",
  31. Age: 18,
  32. }
  33. // 利用给定数据渲染模板,并将结果写入w
  34. tmpl.Execute(w, user)
  35. }

定义结构体

  1. package main
  2. import "fmt"
  3. type Books struct {
  4. title string
  5. author string
  6. subject string
  7. book_id int
  8. }
  9. func main() {
  10. var Book1 Books /* 声明 Book1 为 Books 类型 */
  11. var Book2 Books /* 声明 Book2 为 Books 类型 */
  12. /* book 1 描述 */
  13. Book1.title = "Go 语言"
  14. Book1.author = "www.runoob.com"
  15. Book1.subject = "Go 语言教程"
  16. Book1.book_id = 6495407
  17. /* book 2 描述 */
  18. Book2.title = "Python 教程"
  19. Book2.author = "www.runoob.com"
  20. Book2.subject = "Python 语言教程"
  21. Book2.book_id = 6495700
  22. /* 打印 Book1 信息 */
  23. printBook(&Book1)
  24. /* 打印 Book2 信息 */
  25. printBook(&Book2)
  26. }
  27. func printBook( book *Books ) {
  28. fmt.Printf( "Book title : %s\n", book.title)
  29. fmt.Printf( "Book author : %s\n", book.author)
  30. fmt.Printf( "Book subject : %s\n", book.subject)
  31. fmt.Printf( "Book book_id : %d\n", book.book_id)
  32. }
  33. //结构体new 和赋值
  34. type Person struct {
  35. Username string `json:"username"`
  36. Password string `json:"password"`
  37. }
  38. //声明构造方法
  39. func newPerson(username string, password string) *Person {
  40. return &Person{
  41. Username: username,
  42. Password: password,
  43. }
  44. }
  45. //定义修改结构体的方法
  46. func (p *Person) setUsername(username string) {
  47. p.Username = username
  48. }

map操作

  1. package main
  2. import "fmt"
  3. func main() {
  4. var countryCapitalMap map[string]string /*创建集合 */
  5. countryCapitalMap = make(map[string]string)
  6. /* map插入key - value对,各个国家对应的首都 */
  7. countryCapitalMap [ "France" ] = "巴黎"
  8. countryCapitalMap [ "Italy" ] = "罗马"
  9. countryCapitalMap [ "Japan" ] = "东京"
  10. countryCapitalMap [ "India " ] = "新德里"
  11. /*使用键输出地图值 */
  12. for country := range countryCapitalMap {
  13. fmt.Println(country, "首都是", countryCapitalMap [country])
  14. }
  15. /*查看元素在集合中是否存在 */
  16. capital, ok := countryCapitalMap [ "American" ]
  17. /*删除元素*/ delete(countryCapitalMap, "France")
  18. /*如果确定是真实的,则存在,否则不存在 */
  19. /*fmt.Println(capital) */
  20. /*fmt.Println(ok) */
  21. if (ok) {
  22. fmt.Println("American 的首都是", capital)
  23. } else {
  24. fmt.Println("American 的首都不存在")
  25. }
  26. }
  1. 声明变量
  2. package main
  3. import "fmt"
  4. func main() {
  5. var a string = "Runoob"
  6. fmt.Println(a)
  7. var b, c int = 1, 2
  8. fmt.Println(b, c)
  9. }
  10. 声明方法
  11. package main
  12. import "fmt"
  13. func swap(x, y string) (string, string) {
  14. return y, x
  15. }
  16. func main() {
  17. a, b := swap("Google", "Runoob")
  18. fmt.Println(a, b)
  19. }
  20. 定义数组
  21. var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
  22. var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
  23. package main
  24. import "fmt"
  25. func main() {
  26. var n [10]int /* n 是一个长度为 10 的数组 */
  27. var i,j int
  28. /* 为数组 n 初始化元素 */
  29. for i = 0; i < 10; i++ {
  30. n[i] = i + 100 /* 设置元素为 i + 100 */
  31. }
  32. /* 输出每个数组元素的值 */
  33. for j = 0; j < 10; j++ {
  34. fmt.Printf("Element[%d] = %d\n", j, n[j] )
  35. }
  36. }

Go 语言结构体

  1. package main
  2. import "fmt"
  3. type Books struct {
  4. title string
  5. author string
  6. subject string
  7. book_id int
  8. }
  9. func main() {
  10. var Book1 Books /* 声明 Book1 为 Books 类型 */
  11. var Book2 Books /* 声明 Book2 为 Books 类型 */
  12. /* book 1 描述 */
  13. Book1.title = "Go 语言"
  14. Book1.author = "www.runoob.com"
  15. Book1.subject = "Go 语言教程"
  16. Book1.book_id = 6495407
  17. /* book 2 描述 */
  18. Book2.title = "Python 教程"
  19. Book2.author = "www.runoob.com"
  20. Book2.subject = "Python 语言教程"
  21. Book2.book_id = 6495700
  22. /* 打印 Book1 信息 */
  23. fmt.Printf( "Book 1 title : %s\n", Book1.title)
  24. fmt.Printf( "Book 1 author : %s\n", Book1.author)
  25. fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
  26. fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)
  27. /* 打印 Book2 信息 */
  28. fmt.Printf( "Book 2 title : %s\n", Book2.title)
  29. fmt.Printf( "Book 2 author : %s\n", Book2.author)
  30. fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
  31. fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
  32. }
  33. 结构体作为函数参数
  34. func printBook( book Books ) {
  35. fmt.Printf( "Book title : %s\n", book.title)
  36. fmt.Printf( "Book author : %s\n", book.author)
  37. fmt.Printf( "Book subject : %s\n", book.subject)
  38. fmt.Printf( "Book book_id : %d\n", book.book_id)
  39. }

声明函数和方法区别

  1. #函数
  2. func main() {
  3. sum := add(1, 2)
  4. fmt.Println(sum)
  5. }
  6. func add(a, b int) int {
  7. return a + b
  8. }
  9. #方法
  10. type person struct {
  11. name string
  12. }
  13. func (p person) String() string{
  14. return "the person name is "+p.name
  15. }
  16. func main() {
  17. p:=person{name:"张三"}
  18. fmt.Println(p.String())
  19. }
  20. #可变参数
  21. func main() {
  22. print("1","2","3")
  23. }
  24. func print (a ...interface{}){
  25. for _,v:=range a{
  26. fmt.Print(v)
  27. }
  28. fmt.Println()
  29. }

修改字符串 需要先转换成 byte 或者 rune

  1. func changeString() {
  2. s1 := "hello"
  3. // 强制类型转换
  4. byteS1 := []byte(s1)
  5. byteS1[0] = 'H'
  6. fmt.Println(string(byteS1))
  7. s2 := "博客"
  8. runeS2 := []rune(s2)
  9. runeS2[0] = '狗'
  10. fmt.Println(string(runeS2))
  11. }

原文链接:http://www.cnblogs.com/smallsha/p/14805766.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号