美文网首页
GO的第二天

GO的第二天

作者: 秃头小公主 | 来源:发表于2020-11-06 11:35 被阅读0次

    今天主要去看了一下官方网站,网站:https://gobyexample.com/

    进行了简单的摘要。依旧是不会写博客的一天(有java基础的哦,虽然也不太行)

    Constants:常量

    Slices:切片  s := make([]string, 3) //长度为3的切片

                  fmt.Println("len:", len(s))//返回长度

                  s = append(s, "d")//压入新的

                  l := s[2:5]//得到一个包含元素 s[2]、s[3] 和 s[4] 的 slice (做包右面不包除非【2:】后面都包括) 

    Map:关联数据类型    m := make(map[string]int)//创建新的map

                      n := map[string]int{"foo": 1, "bar": 2}//声明并初始化map

                      m["k1"] = 7//设置键值对 

                      fmt.Println("len:", len(m))//内建函数 len 可以返回一个 map 的键值对数量。

                      delete(m, "k2")//内建函数 delete 可以从一个 map 中移除键值对。

    Range 遍历(for)      for _, num := range nums {sum += num}//无索引遍历(无key)

                        for i, num := range nums {if num == 3 {fmt.Println("index:", i)}}//有索引value=3时返回key

                        for i, c := range "go" { fmt.Println(i, c) }//range 在字符串中迭代 unicode 码点(code point)。 第一个返回值是字符的起始字节位置,然后第二个是字符本身。

    函数    func plusPlus(a, b, c int) int { return a + b + c}//a,b,c类型相同可以只声明最后一个

            多返回值(同时返回结果和错误信息)      func vals() (int, int) {return 3, 7}//(int,int)表示返回两个int

                                                  _, c := vals()//仅返回一部分即7

            变参函数      func sum(nums ...int) {}//接受任意数量的int                 

                          sum(nums...)// func函数名(slice切片...)直接求和

            函数特性

                          闭包  https://gobyexample-cn.github.io/closures

                          递归  https://gobyexample-cn.github.io/recursion

    指针    func zeroptr(iptr *int) {*iptr = 0}//*int代表使用指针,*iptr解引用这个指针

            zeroptr(&i)//通过&i取得i的内存地址

            fmt.Println("zeroptr:", i)

            fmt.Println("pointer:", &i)//打印地址

    结构体  type 结构体名persnon struct { name string  age  int}//创建结构体

            fmt.Println(person{"Bob", 20})//创建新的结构体元素

            fmt.Println(person{name: "Alice", age: 30})//可以指定字段元素

            fmt.Println(person{name: "Fred"})//省略字段初始化为零

            fmt.Println(&person{name: "Ann", age: 40})//& 前缀生成一个结构体指针。

            fmt.Println(s.name)//s的name,用“.”

            sp.age = 51//结构体可变,重新赋值51

    方法  支持位结构体定义方法

          func (r *rect) area() int {return r.width * r.height}//接受*rect,返回int

    接口    type geometry interface {area() float64 perim() float64}//接口的实现

            func measure(g geometry) {}//通常使用measure函数来实现,通过它使用所有的接口

    错误处理  func f1(arg int) (int, error) {//返回一个int和一个错误

                  if arg == 42 {return -1, errors.New("can't work with 42")//构建error

                  return arg + 3, nil//返回错误值为 nil 代表没有错误

              }

              type argError struct { arg  int prob string }//可以自定义错误类型

              func (e *argError) Error() string {

                  return fmt.Sprintf("%d - %s", e.arg, e.prob)

              }//Sprint格式化输出,输出形式为%d - %s

              for _, i := range []int{7, 42} {//在if的同一行进行错误检查

                        if r, e := f1(i); e != nil {

                            fmt.Println("f1 failed:", e)

                        } else {

                            fmt.Println("f1 worked:", r)

                        }

                }

    协程:量级的执行线程      go f("goroutine")//多线程开启,并发开启

                            go func(msg string) { fmt.Println(msg) }("going")//传入going并发异步执行

                            time.Sleep(time.Second)//等待进程完成,更好的方法是使用 WaitGroup

                            go func(){}()//以并发的形式调用函数

    通道:连接多个协程的管道        messages := make(chan string)//创建新的通道(通道类型就是要传递值的类型)

                                go func() { messages <- "ping" }()//channel <-值,这样发送值到通道

                                msg := <-messages//接受通道里的值

            通道缓冲:允许在没有对应接收者的情况下,缓存一定数量的值

                      messages := make(chan string, 2)//最多允许缓存两个值的通道

                      messages <- "buffered"  messages <- "channel"//直接发送,无需发送之后马上接收

            通道同步:可以使用通道来同步协程之间的执行状态

                      func worker(done chan bool) {//一个叫done的通道和一个bool

                            fmt.Print("working...")

                            time.Sleep(time.Second)

                            fmt.Println("done")

                            done <- true//done用于通知工作ok

                            如果你把 <- done 这行代码从程序中移除, 程序甚至可能在 worker 开始运行前就结束了。

                      }

            通道方向:可以指定这个通道是否为只读或只写,可以提升程序的安全性

                      func ping(pings chan<- string, msg string) {//定义了只写(发送)权限

                                    pings <- msg

                      }

                    func pong(pings <-chan string, pongs chan<- string) {//接收两个通道,pings用于只读(接受),pongs用于只写(发送)

                                    msg := <-pings

                                    pongs <- msg

                    }

              通道选择器:可以同时等待多个通道操作

                        select {}//用select关键字来同时等待这两个值,默认处理第一个准备好的接受操作

                        time.Sleep(1 * time.Second)//等待的时间短的先输出,程序运行的时间是等待长的时间而不是和

              超时处理        case <-time.After(1 * time.Second)://等待时间之后向通道传入

                            select {

                                        case res := <-c1:

                                              fmt.Println(res)

                                        case <-time.After(1 * time.Second)://如果操作耗时超过了允许的 1 秒(时间),执行这个

                                              fmt.Println("timeout 1")

                              }

                              如果正常时间<超时时间,则不触发超时时间

              非阻塞通道操作:常规通道是阻塞的。 可以用default,select实现非阻塞发送、接收,甚至是非阻塞的多路 select。

                          msg := "hi"

                          select {

                                      case messages <- msg:

                                              fmt.Println("sent message", msg)//发送msg必须有人收才会被选中,否则不会。

                                      default:

                                              fmt.Println("no message sent")//输出结果为这个

                                  }

                            select {

                                        case msg := <-messages://如果messages有值(接收必须有人发才会被选中)

                                                fmt.Println("received message", msg)

                                        case sig := <-signals://如果signals有值

                                                fmt.Println("received signal", sig)

                                        default://否则

                                                fmt.Println("no activity")

                            }

              通道的关闭:这个特性可以让通道的接收方知道工作完成

                        j, more := <-jobs//工作完成或关闭通道more为false

                        if more {}

                        else {

                                fmt.Println("received all jobs")

                                done <- true

                                return

                        }

                        close(jobs)//关闭通道

                        <-done//等待工作结束

              通道遍历:类似for和range

                      queue := make(chan string, 2)

                      queue <- "one"

                      queue <- "two"

                      close(queue)//非空通道也可以关闭,关闭后可以正常接收

                      for elem := range queue { fmt.Println(elem) }//循环输出通道的值

    Timer:定时器在一定时间之后要发生的事,它会提供一个用于通知的通道。与sleep的区别在于定时器可以在定时器触发之前取消。需要import time

          timer1 := time.NewTimer(2 * time.Second)//这里的定时器等待2秒

          <-timer1.C//c为定时器通道

          stop2 := timer2.Stop()//停止定时器

    Ticker:打点器在固定的时间间隔重复执行知道主动停止,停止后不能接受值

          ticker := time.NewTicker(500 * time.Millisecond)//创建打点器

          case t := <-ticker.C:  fmt.Println("Tick at", t)//触发打点器

          ticker.Stop()//结束打点器

    相关文章

      网友评论

          本文标题:GO的第二天

          本文链接:https://www.haomeiwen.com/subject/zactbktx.html