Go语言-函数、协程以及依赖入门

68 阅读3分钟

函数

5.1 函数声明

每个函数声明都包含一个名字、一个形参列表、一个可选的返回列表以及函数体:

func name(parameter-list) (result-list) {
    body
}

形参列表指定了一组变量的参数名和参数类型,这些局部变量都由调用者的实参传递而来。返回列表则指定了函数返回值的类型。当函数返回一个未命名的返回值或者没有返回值的时候,返回列表的圆括号可以省略。如果一个函数既省略返回列表也没有任何返回值,那么设置这个函数的目的是调用函数之后带来的附加效果。

func add(x int, y int) int {return x + y}
func sub(x, y int) (z int) {z = x - y; return}
func first(x int, _ int) int {return x}
func zero(int, int) int {return 0}

函数的类型称作函数签名。 当两个函数拥有相同的形参列表和返回列表时,认为这两个函数的类型或签名是相同的。而形参和返回值的名字不会影响到函数类型,采用简写同样也不会影响到函数的类型。但调用函数时,参数的调用顺序必须一致。 Go语言没有默认参数值的概念也不能指定实参名。形参变量都是函数的局部变量初始值由提供的实参传递。函数形参以及命名返回值同属于函数最外层作用域的局部变量。

作用域解释
全局作用域全局作用域是指在函数外部定义的变量和函数,它们的作用域可以跨越整个程序。
包级别作用域包级别作用域是指在包内定义的变量和函数,它们的作用域在整个包内部都可见。
函数级别作用域函数级别作用域是指在函数内定义的变量和函数,它们的作用域只在该函数内部有效,函数参数也属于该级别作用域。
代码块级别作用域代码块级别作用域是指在代码块内定义的变量和函数,它们的作用域只在该代码块内部有效。例如在 if、for、switch 语句中定义的变量就是代码块级别作用域。

实参是按值传递的,所以函数接收到的是每个实参的副本;修改函数的形参变量一般不会影响到调用者提供的形参。然而,如果提供的实参包含引用类型,比如指针、slice、map、函数或者通道,那么当函数使用形参变量时就有可能会间接地修改实参变量。

func Sin(x float64) float64 // 使用汇编语言实现

GoRoutine

package demoA
​
import (
    "fmt"
    "time"
)
​
func hello(i int) {
    println("hello goroutine : " + fmt.Sprint(i))
}
​
func HelloGoRoutine() {
    for i := 0; i < 5; i++ {
        go func(j int) {
            hello(j)
        }(i)
    }
    time.Sleep(time.Second)
}
​

引文

提倡通过通信共享内存而不是通过共享内存而实现通信。通过通信共享内存的主要方式是使用通道;而通过共享内存而实现通信是使用临界区。

Channel 通道

分为无缓冲通道和有缓冲通道(左图为无缓冲通道,右图为缓冲通道)

make(chan 元素类型, [缓冲大小])

并发安全 Lock

关键是对临界区的权限控制

WaitGroup

var wg sync.WaitGroup
​
wg.Add()
wg.Done()
wg.Wait()

依赖管理

依赖配置-依赖图

选择最低的兼容版本

依赖分发-回源

  1. 无法保证构建稳定性

    1. 增加、修改、删除软件版本
  2. 无法保证依赖可用性

    1. 删除软件
  3. 增加第三方压力

    1. 代码托管平台负载问题

依赖分发-Proxy

稳定、可靠(适配器)

依赖分发-变量 GOPROXY

工具

go get

······

go mod
命令功能
init初始化,创建go.mod文件
download下载模块到本地缓存
tidy增加需要的依赖,删除不需要的依赖