入门笔记 --- Golang 语法注意事项(一)

1. import 写法

  • 导入标准库或其他模块

    • 导入标准库,直接写库的名称即可

    • 导入其他模块可以使用相对路径或绝对路径

      import (
         "fmt"  // 库的名称
         "./modal" // 绝对路径
         "my/modal" // 相对路径(GOPATH/src/my/modal)  
      )
      
  • 特殊的导入包的使用方法

    • 点操作
      使用点操作导入的包你可以直接使用包内的函数而省略包名如fmt.Print()可以写成Print()

    • 别名操作

      当你导入的包名称比较难记忆或者有命名冲突的时候,你可以使用别名操作可以把包命名成一个另外一个不会冲突且容易记忆的名称

    • _ 操作
      该操作只是引入一个包。当它导入一个包时,包所有的init()函数都会执行,但是我们无法通过包名等来调用包内的导出函数(我们有时候只需要包的init()函数而不需要其他函数)
      所以,该操作的作用只是用来调用包的init() 函数

      import (
          . "fmt" // 点操作
          f "fmt" // 别名操作
          _ "my/modal" // _ 操作
      )
      
  • import 导入包的过程
    程序的初始化和执行都从main包开始,如果,mian包还导入了其他的包,那么在main包中,会先导入其他的包(其余包也一样),然后再将包的全局常量和变量进行初始化,接着在执行init()函数,最后在执行main函数。在导入的其余包中,重复导入包、初始化常量、变量、执行init操作。
    入门笔记 --- Golang 语法注意事项(一)_第1张图片

2.双引号、单引号、反引号 & byte与rune区别

  • 双引号表示字符串string,其实质是一个byte类型的数组,Go语言的字符串的字节使用UTF-8编码标识Unicode文本。它创建的字符串是可解析、可转义的字符串字面量,但是它不支持多行.

    golang中string底层是通过byte数组实现的。中文字符在unicode下占2个字节,在utf-8编码下占3个字节,而golang默认编码正好是utf-8。所以, str=“abc 中文” 长度为10

  • 单引号表示rune类型,该类型是int32的别名,功能与int32相差无几。它创建的是码点字面量,是不做任何转义的原始内容.

    它与byte类型类似,都用来表示字符类型的变量,但是

    • byte 等同于int8,常用来处理ascii字符
    • rune 等同于int32,常用来处理unicode或utf-8字符

    所以在使用rune类型将str = “abc 中文” 转化类型,即 len([]rune(str))的值为6

  • 反引号是用来创建字符串,但是它创建的是原生的字符串字面量(与双引号表示的string不同),它可以由多行组成,但是不支持任何转义序列,原生的字符串字面量多用于书写多行消息、HTML以及正则表达式。

3.变量声明后默认值

  • 数字类型(包括整型、浮点型:int8、byte、int16、uint、uintprt、float32、float64):默认值为0。
  • 布尔类型(bool):默认值为false。
  • 复数类型(complex64、complex128):默认值为0+0i。
  • 字符串(string):默认值为”“。
  • 错误类型(error):默认值为nil。
  • 派生类型:其中如:指针、切片、字典、通道、接口等:默认值为nil。而数组的默认值要根据其数据类型来确定。例如:var a [4]int,其默认值为[0 0 0 0]。

4.错误捕获&异常处理机制

  • 其他语言处理机制
    在Java、JavaScript、PHP等语言中,异常处理是依靠try…catch、throw来处理。

    try{
       // 可能发生异常的语句
    }catch(e){
       // 捕获到错误e,停止执行上面的语句,跳转到这个代码块
    }finally{
       // 无论上述代码块怎么执行,这部分代码都肯定执行
    }
    
    throw Error("") // 抛出错误,可被try...catch捕获
    
  • go错误处理机制
    在go中,依靠panic、recover函数来处理,它们的作用分别与throw和catch语句相似,当然也存在不同之处。

  • panic函数

    func panic(interface{})//接受任意类型参数 无返回值
    
    • panic可以将原有的控制流程中断,进入到一个"恐慌"流程。这种恐慌流程可以显式调用panic()函数产生或者由运行时错误产生(例如访问越界的数组下标)。
    • panic会在调用它的函数中向本层和它的所有上层逐级抛出,若一直没有recover将其捕获,程序退出后会产生crash。
    • panic并不会影响defer的函数的执行。
    • 与其他语言throw相识,会抛出异常。
  • recover函数

    func recover() interface{}//可以返回任意类型 无参数
    
    • 它是一个内建函数,可以使进入令人恐慌的进行中的goroutime恢复(即捕获panic抛出的异常)。
    • 在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。
    • 功能与其他语言的catch相似,可以捕获异常。
    • 一般情况下,recover()应该在一个使用defer关键字的函数中执行以有效截取错误处理流程。如果没有在发生异常的goroutine中明确调用恢复
  • defer函数

    • 它是go的延迟执行语句,它会延迟执行一个函数,在他所属的那个函数的return将结果写入返回值后,才执行被延迟的函数

    • defer执行顺序

           * 执行到return语句->
           * return给返回值赋值->
           * 执行的defer延迟的函数->
           * 函数携带返回值返回
      
    • 多个defer的执行顺序为LIFO(后进先出),所有的的份儿保存在一个延迟调用栈

    • defer修饰的函数值和参数取值都会在defer语句执行时保存,等到上一级函数返回时,按LIFO执行defer函数

      如果函数的参数为指针,则需要注意函数执行时,参数是否修改,因为defer执行时,保存的也是参数的指针

    • defer函数的任何返回都会被丢弃

    • 如果一个defer的函数值为nil,则这个defer函数会在函数执行时panic(异常),而不是在defer语句执行时。

    • 如果defer修饰的是一个含有闭包的函数(同时你也想让闭包函数执行)

      • 那么你需要定义一个变量,将函数返回的闭包复制给这个变量后再修饰这个变量
      func test(){
           return func(){}
      }
      test1 := test()
      defer test1
      
      • 或者你直接在修饰的后面再加个()代表返回的闭包立即执行
      defer test()()
      

你可能感兴趣的:(Golang)