Go语言笔记

Go

Posted by kaws-y on January 9, 2024

GO

关键字 defer

  • 当defer被声明时,其参数就会被实时解析
      func main() {
      	var i int = 1
        
      	defer fmt.Println("result =>", func() int { return i * 2 }())
      	i++
      	// 输出: result => 2 (而不是 4)
      }
    
  • defer执行顺序为先进后出
  • defer可以读取有名返回值,也就是可以改变有名返回参数的值。
      func changereturn()(result i) {
          defer func(){
              result = 12
          }()
          retrun
      }
    

切片

slice是对底层数组一个连续片段的引用,是一个引用类型。未初始化切片的值为nil.我们可以理解切片为一个长度可变的数组。    `cap()函数`    slice提供了计算容量的函数`cap()`,可以测量切片的最大长度,切片的长度永远不会超过他的容量。所以这个不等式永远成立:0 <= len(s) <= cap(s)    `make()函数`    使用内置函数`make()`可以给切片初始化,该函数指定切片类型和指定长度和可选容量的参数。  >  var slice1 []type = arr1[start:end]

append函数 使用append函数可以向切片追加元素,如果超过了切片容量,会自动扩展底层数组

切片操作

    // 使用切片操作 sli[:4] 获取从开头到索引 4(不包括索引 4)的所有元素
   silce := str[:4]
    // 使用切片操作 sli[1:] 获取从索引 1 开始到末尾的所有元素
   silced := str[1:]

select 控制

select是go中的控制结构,类似switch语句,用于处理异步通道操作,select中的case语句必须是一个channel操作,default子句总是可运行的

  • 如果有多个分支都可以运行,select会伪随机公平地选出一个执行,其他分支不会执行。
  • 如果没有可运行的分支,且有default语句,那么就会执行default的动作。
  • 如果没有可运行的分支,且没有default语句,select将阻塞,直到某个分支可以运行。

Panic

在go中,panic()是一个内置函数,用于表示非常严重不可恢复错误,必须要先声明defer,否则不能捕获到异常。 在多层嵌套的函数调用中调用 panic(),可以马上中止当前函数的执行,所有的 defer 语句都会保证执行并把控制权交还给接收到异常的函数调用者。这样向上冒泡直到最顶层,并执行(每层的) defer,在栈顶处程序崩溃,并在命令行中用传给异常的值报告错误情况:这个终止过程就是 panicking。

function

基本组成:关键字func、函数名、参数列表、返回值、函数体和返回语句.除了main()和init()函数之外都可以有参数和返回值。默认值传递,如果想引用传递,需要传递给函数一个指针,比如说func(&arg1)

    func 函数名(参数列表) (返回值列表) {
        // 函数体
    return
    } 

内置函数

new()、make()、close():

make() 只用于slice、map以及channel这三种引用数据类型的初始化和内存分配。new()用于值类型的内存分配并置为零值。close() 用于通道,对于通道c,内置函数close(c)将不再在通道c发送值,如果c是仅接收通道,则会出错。 发送或关闭已关闭的通道会导致运行时错误。 关闭nil通道也会导致运行时错误。

interface

接口(interface)类型是Go语言的一种数据类型。而因为所有的类型包括自定义类型都实现了空接口interface{},所以空接口interface{}可以被当做任意类型的数值。 Go 语言中的所有类型包括自定义类型都实现了interface{}接口,这意味着所有的类型如string、 int、 int64甚至是自定义的结构体类型都拥有interface{}空接口,这一点interface{}和Java中的Object类比较相似。

    var i interface{} = 99 // i可以是任何类型
    i = 44.09
    i = "All"  // i 可接受任意类型的赋值

channel

go奉行通过通信来共享内存,而不是共享内存来通信。channel 是协程之间互相通信的通道,协程之间可以通过它发送消息和接收消息。 通道是进程内的通信方式,因此通过通道传递对象的行为与函数调用时参数传递行为比较一致,比如也可以传递指针等。 通道消息传递与消息类型也有关系,一个通道只能传递(发送send或接收receive)类型的值,这需要在声明通道时指定。 默认情况下,通道是阻塞的 (叫做无缓冲的通道)。 使用make来建立一个通道:

    var channel chan int = make(chan int)
    // 或
    channel := make(chan int)

Go中通道可以是发送(send)、接收(receive)、同时发送(send)和接收(receive)

    // 定义接收的通道
    receive_only := make (<-chan int)
     
    // 定义发送的通道
    send_only := make (chan<- int)
    
    // 可同时发送接收
    send_receive := make (chan int)
···