NO.1 GO语言基础入门学习笔记 | 青训营

74 阅读7分钟

本文主要分为两个部分:一是字节跳动后端训练营课程笔记;二是课外教程补充笔记

掘金课程笔记

基础语法

  1. 变量声明:var a="aaa"
  2. if else: 无括号
  3. for循环:无括号
  4. switch:判断变量可为任意类型,case后面可接表达式
  5. 数组:var a[100] int
  6. 切片:针对字符串有append、copy等函数对任意字符进行操作
  7. map:类key-value形式,capital["china"]="Beijing"
  8. range:直接声明数组,for k,v:=range n{fmt.Println(k, v)}
  9. 函数: func 函数名(形式参数名 形式参数类型) 返回值类型{}
  10. 指针:value *int
  11. 结构体:

image.png

  1. 错误处理

image.png

  1. 字符串操作

image.png 14. Json处理

image.png 15. 时间处理

image.png 16. 数字解析

image.png

  1. 进程信息

image.png

课外补充教程笔记

  1. 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如: Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected)。

  2. 需要注意的是 { 不能单独放在一行

  3. 关键字

    下面列举了 Go 代码中会使用到的 25 个关键字或保留字:

    breakdefaultfuncinterfaceselect
    casedefergomapstruct
    chanelsegotopackageswitch
    constfallthroughifrangetype
    continueforimportreturnvar

    除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:

    appendboolbytecapclosecomplexcomplex64complex128uint16
    copyfalsefloat32float64imagintint8int16uint32
    int32int64iotalenmakenewnilpanicuint64
    printprintlnrealrecoverstringtrueuintuint8uintptr
  4. 在函数调用时,函数名和左边等号之间要使用空格,参数之间也要使用空格。

    result := add(2, 3)

  5. 派生类型: 包括:

    • (a) 指针类型(Pointer)
    • (b) 数组类型
    • (c) 结构化类型(struct)
    • (d) Channel 类型
    • (e) 函数类型
    • (f) 切片类型
    • (g) 接口类型(interface)
    • (h) Map 类型
  6. iota

    iota,特殊常量,可以认为是一个可以被编译器修改的常量。

    iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

    iota 可以被用作枚举值:

    const (
        a = iota
        b = iota
        c = iota
    )
    

    第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

    const (
        a = iota
        b
        c
    )
    

    iota 用法

    package main
    import "fmt"
    func main() { const ( 
    a = iota //0 
    b //1 
    c //2 
    d = "ha" //独立值,iota += 1 
    e //"ha" iota += 1 
    f = 100 //iota +=1 
    //100 iota +=1 
    h = iota //7,恢复计数 
    i //8 ) 
    fmt.Println(a,b,c,d,e,f,g,h,i) 
    }
    

    以上实例运行结果为:

    0 1 2 ha ha 100 100 7 8
    
  7. 函数定义

    Go 语言函数定义格式如下:

    func function_name( [parameter list] ) [return_types] {
       函数体
    }
    
  8. package main

    import "fmt"

    func swap(x, y string) (string, string) { return y, x }

    func main() { a, b := swap("Google", "Runoob") fmt.Println(a, b) }

  9. 声明数组

    Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:

    var arrayName [size]dataType
    

    其中,arrayName 是数组的名称,size 是数组的大小,dataType 是数组中元素的数据类型。

    以下定义了数组 balance 长度为 10 类型为 float32:

    var balance [10]float32
    
  10. 初始化数组

    以下演示了数组初始化:

    以下实例声明一个名为 numbers 的整数数组,其大小为 5,在声明时,数组中的每个元素都会根据其数据类型进行默认初始化,对于整数类型,初始值为 0。

    var numbers [5]int
    

    还可以使用初始化列表来初始化数组的元素:

    var numbers = [5]int{1, 2, 3, 4, 5}
    

    以上代码声明一个大小为 5 的整数数组,并将其中的元素分别初始化为 1、2、3、4 和 5。

    另外,还可以使用 := 简短声明语法来声明和初始化数组:

    numbers := [5]int{1, 2, 3, 4, 5}
    

    以上代码创建一个名为 numbers 的整数数组,并将其大小设置为 5,并初始化元素的值。

    注意: 在 Go 语言中,数组的大小是类型的一部分,因此不同大小的数组是不兼容的,也就是说 [5]int[10]int 是不同的类型。

    以下定义了数组 balance 长度为 5 类型为 float32,并初始化数组的元素:

    var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    

    我们也可以通过字面量在声明数组的同时快速初始化数组:

    balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    

    如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度:

    var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    或
    balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    

    如果设置了数组的长度,我们还可以通过指定下标来初始化元素:

    //  将索引为 1 和 3 的元素初始化
    balance := [5]float32{1:2.0,3:7.0}
    

    初始化数组中 {} 中的元素个数不能大于 [] 中的数字。

    如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:

     balance[4] = 50.0
    

    以上实例读取了第五个元素。数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。

  11. nil 指针也称为空指针。

  12. 结构体

    type Books struct { title string author string subject string book_id int }

  13. 定义切片

    你可以声明一个未指定大小的数组来定义切片:

    var identifier []type
    

    切片不需要说明长度。

    或使用 make() 函数来创建切片:

    var slice1 []type = make([]type, len)
    ​
    也可以简写为
    ​
    slice1 := make([]type, len)
    

    也可以指定容量,其中 capacity 为可选参数。

    make([]T, length, capacity)
    

    这里 len 是数组的长度并且也是切片的初始长度。

  14. range

    for key, value := range oldMap { newMap[key] = value }

  15. 遍历简单的数组,2%d** 的结果为 2 对应的次方数

  16. 定义 Map

    可以使用内建函数 make 或使用 map 关键字来定义 Map:

    /* 使用 make 函数 */
    map_variable := make(map[KeyType]ValueType, initialCapacity)
    

    其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。

  17. str := "123" num, err := strconv.Atoi(str)

  18. 指定转接口:

    T(value)
    
  19. 接口转指定:

    value.(type) 
    或者 
    value.(T)
    
  20. 定义接口

type interface_name interface { 
method_name1 [return_type] 
method_name2 [return_type] 
method_name3 [return_type]  
method_name4 [return_type] 
}
  1. 错误处理

    func Sqrt(f float64) (float64, error) { 
    if f < 0 { 
    return 0, errors.New("math: square root of negative number") 
    } // 实现 
    }
    
  2. Go 并发

    Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。

    goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。

    goroutine 语法格式:

    go 函数名( 参数列表 )
    

    例如:

    go f(x, y, z)
    

    开启一个新的 goroutine:

    f(x, y, z)
    

    Go 允许使用 go 语句开启一个新的运行期线程, 即 goroutine,以一个不同的、新创建的 goroutine 来执行一个函数。 同一个程序中的所有 goroutine 共享同一个地址空间。

    func main() { **go** say("world") say("hello") }

    输出的 hello 和 world 是没有固定先后顺序。因为它们是两个 goroutine 在执行:

  3. 通道(channel)

    通道(channel)是用来传递数据的一个数据结构。

    通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

    ch <- v    // 把 v 发送到通道 ch
    v := <-ch  // 从 ch 接收数据
               // 并把值赋给 v
    

    声明一个通道很简单,我们使用chan关键字即可,通道在使用前必须先创建:

    ch := make(chan int)
    

    注意:默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据。