Go语言基础| 青训营笔记

434 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天


这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

Part1--Go语言基础:

基础部分 -- 包的导入

  1. 包: 每个 Go 程序都是由包构成的。
  2. 导入: eg: import "fmt"导入相关库 相关库导入后可以使用相关的函数
  3. 导出: 在 Go 中,如果一个名字以大写字母开头,那么它就是已导出的。例如,Pizza 就是个已导出名,Pi 也同样,它导出自 math 包 Go中从包里调用的内容 只有导出的才会被识别

基础部分 -- 函数和变量

  1. 函数的声明方式:

    1. func关键字
        需要用func标识是函数
    2. xxx 函数名 
        自定义函数名
    3.传入参数:
        传入的参数有多个 特殊属性:可以连续多个同类的传入变量之用一个type放在最后标记
    4.返回值:  
        返回值可以有多个 特殊属性: 可以给返回值命名之后直接return
    
  2. 数据类型:

    1.bool //布尔值类型
    
    2.string //字符串
    
    3.int  int8  int16  int32  int64 //整型
     
    4.uint uint8 uint16 uint32 uint64 uintptr //无符号整型
    
    5.byte // uint8 的别名
    
    6.rune // int32 的别名// 表示一个 Unicode 码点
    
    7.float32 float64 //浮点数
    
    8.complex64 complex128 //复数
    
  3. 变量和变量的初始化

     1. 变量的声明 var xxx yyy type
     2. 变量的初始化 var xxx yyy int = 1 , 2 
     3. 短变量的声明以及初始化 :在函数中,简洁赋值语句 `:=` 可在类型明确的地方代替 `var` 声明
     4. `:=` 结构不能在函数外使用。
    
  4. 常量

     1. 常量的声明与变量类似,只不过是使用 `const` 关键字。
     2. 常量可以是字符、字符串、布尔值或数值。
     3. 常量不能用 `:=` 语法声明。
     4. `const`定义的值是高精度的值 
    
     eg: const Pi = 3.1415926
    
  5. 数值转换

      1. go中不支持隐式转换 所有的转换必须显式进行 T(v) 进行转换
    

基础部分 -- 流程控制: if, for , switch , defer

  1. 循环

     Go 只有一种循环结构:`for` 循环。
     基本的 `for` 循环由三部分组成,它们用分号隔开:
     -   初始化语句:在第一次迭代前执行
     -   条件表达式:在每次迭代前求值
     -   后置语句:在每次迭代的结尾执行
     初始化语句通常为一句短变量声明,该变量声明仅在 `for` 语句的作用域中可见。
     一旦条件表达式的布尔值为 `false`,循环迭代就会终止。
     
     1. 初始化语句和后置语句是可选的。
     2. 当不需要初始化语句和后置语句时可以不写`;`而写判断语句
     3. 死循环: 直接写for{}
    

    注意:和 C、Java、JavaScript 之类的语言不同,Go 的 for 语句后面的三个构成部分外没有小括号,而大括号 { } 则是必须的。

  2. 判断

     1.同 `for` 一样, `if` 语句可以在条件表达式前执行一个简单的语句。
     2.该语句声明的变量作用域仅在 `if` 之内。
     3.标准格式 if 初始化;条件 { } 
     4.switch: Go 的 switch 语句类似于 C、C++、Java、JavaScript 和 PHP 中的,不过 Go 只运行选定的 case,而非之后所有的 case。 实际上,Go 自动提供了在这些语言中每个 case 后面所需的 `break` 语句。
     5. 没有条件的 switch 代替大量的if-else
    
  3. defer语句

     1.defer语句会立即进行求值 但是等外层函数结束返回时才会执行
     2.defer栈: 被执行的defer语句保持先进后出
    

基础部分 -- 指针 , 结构体 , slice , 映射 , 闭包

  1. 指针

     与 C 不同,Go 没有指针运算。
    
  2. 结构体

     1.声明方式: type sturct xxx { 成员 }
     2.赋值方法:
         1. 利用大括号全部赋值
         2. 成员名+ : 对局部赋值
    

3.数组和切片

    1.数组: 和C相同 连续空间
    2.切片: 切片本质上是一种对应底层数组的指针+len+cap的复合
        1. 切片的截取方式 var xxx []int = yyy[1:4] 1-4的一个映射 此时len==3 cap为从1到末尾的大小 
        2. 切片容量的改变: 一旦改变了起始位置 那么容量cap的大小就会发生改变
        3. 切片的长度和容量 : lencap进行获取 
        4. append向后追加 扩容方式: 小于1024的时候是二倍 而后变为1.256. 切片会影响到底层数组
        7. make(类型和名称 , 长度 , 容量)

4.range遍历

    当使用 `for` 循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本
    可以将下标或值赋予 _ 来忽略它。
        for i, _ := range pow
        for _, value := range pow
    若你只需要索引,忽略第二个变量即可。
        for i := range pow
        

5.映射

    声明: var m map[string]int 下标为string val为int
    在映射 `m` 中插入或修改元素:
        m[key] = elem
    获取元素:
        elem = m[key]
    删除元素:
        delete(m, key)
    通过双赋值检测某个键是否存在:
        elem, ok = m[key]
        若 `key` 在 `m` 中,`ok` 为 `true` ;否则,`ok` 为 `false`。
        若 `key` 不在映射中,那么 `elem` 是该映射元素类型的零值。
        同样的,当从映射中读取某个不存在的键时,结果是映射的元素类型的零值。
    **注** :若 `elem` 或 `ok` 还未声明,你可以使用短变量声明:
    elem, ok := m[key]
   

6.闭包:

    1. 类似结构体封装了值和方法
    2. func adder() func(int) int {
            sum := 0
            return func(x int) int {
                    sum += x
                    return sum
            }
        }
       当别人调用 adder的时候返回的是一个闭包 里面有一个 sum值还有一个方法func 
       pos, neg := adder(), adder()
                for i := 0; i < 10; i++ {
                        fmt.Println(
                                pos(i),
                                neg(-2*i),
                        )
                }
        }
        如上文 当pos(i)的时候 其实调用了内部的方法对sum进行了一次修改 各个修改相互独立

码风略丑,读者见谅 --2023/1/15