函数
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()
依赖管理
依赖配置-依赖图
选择最低的兼容版本
依赖分发-回源
-
无法保证构建稳定性
- 增加、修改、删除软件版本
-
无法保证依赖可用性
- 删除软件
-
增加第三方压力
- 代码托管平台负载问题
依赖分发-Proxy
稳定、可靠(适配器)
依赖分发-变量 GOPROXY
工具
go get
······
go mod
| 命令 | 功能 |
|---|---|
| init | 初始化,创建go.mod文件 |
| download | 下载模块到本地缓存 |
| tidy | 增加需要的依赖,删除不需要的依赖 |