> ### 函數 function
* 函數(不支持 嵌套、重載和默認參數, 可以將函數作為一個值進行賦值)
~~~
package main
import "fmt"
func add(number1 int, number2 int) (number3 int) {
number3 = number1 + number2
return
}
func subtraction(number1, number2 int) int {
number3 := number1 - number2
return number3
}
func multiplication(number ...int) int {
total := 1
for _, v := range number {
total *= v
}
return total
}
func demo1() {
fmt.Println(add(8, 7))
fmt.Println(subtraction(8, 7))
fmt.Println(multiplication(2, 3, 5, 10))
}
func main() {
demo1()
}
~~~
* 匿名函數(通常不希望再次使用(即只使用一次)的函數可以定義為匿名函數)
~~~
package main
import "fmt"
func demo2() {
//f1為函數地址
f1 := func(x, y int) int {
z := x + y
return z
}
fmt.Println(f1)
fmt.Println(f1(5, 6))
//直接創建匿名函數并運行
f2 := func(x, y int) int {
z := x + y
return z
}(5, 6)
fmt.Println(f2)
//直接創建匿名函數并運行(無參數的形式) ()調用匿名函數
func() {
fmt.Println(5 + 6)
}()
}
func main() {
demo2()
}
~~~
* 閉包函數 (函數內在包含子函數,并最終return子函數)
~~~
package main
import "fmt"
func number1(x int) func(y int) int {
return func(y int) int {
return x + y
}
}
func number2() func() {
return func() {
fmt.Println("Hello World!")
}
}
func demo3() {
n1 := number1(7)
fmt.Println(n1(8))
n2 := number2()
n2()
}
func main() {
demo3()
}
~~~
* 閉包函數2
~~~
package main
import (
"fmt"
)
func Number(i int) func() {
return func() {
fmt.Println(i)
}
}
func main() {
number1 := make([]func(), 3)
number2 := make([]func(), 3)
//TODO:1
//閉包可以直接使用外部的變量
for i := 0; i < 3; i++ {
number1[i] = func() {
fmt.Println(i)
}
}
fmt.Println("-----TODO1-----")
for _, v := range number1 {
v()
}
//TODO:2
for i := 0; i < 3; i++ {
j := i
number2[i] = func() {
fmt.Println(j)
}
}
fmt.Println("-----TODO2-----")
for _, v := range number2 {
v()
}
}
~~~
* 遞歸
~~~
package main
import "fmt"
/*棧空間變化(堆棧從左到右,增加到一個峰值后再計算從右到左縮小)
demo4(5)
5 + demo4(4)
5 + (4 + demo4(3))
5 + (4 + (3 + demo4(2)))
5 + (4 + (3 + (2 + demo4(1))))
5 + (4 + (3 + (2 + 1)))
5 + (4 + (3 + 3))
5 + (4 + 6)
5 + 10
15
*/
func demo4(val int) int {
if val > 0 {
return val + demo4(val-1)
} else {
return val
}
}
func main() {
fmt.Println(demo4(5))
}
~~~
* 尾遞歸
~~~
package main
import "fmt"
/*棧空間變化
demo5(5, 0)
demo5(4, 5)
demo5(3, 9)
demo5(2, 12)
demo5(1, 14)
demo5(0, 15)
15
*/
func demo5(val int, total int) int {
if val > 0 {
return demo5(val-1, total+val)
} else {
return total
}
}
func main() {
fmt.Println(demo5(5, 0))
}
~~~
* 迭代
~~~
package main
import "fmt"
func demo6(number int) int {
total := 0
for {
if number > 0 {
total += number
number--
} else {
break
}
}
return total
}
func main() {
fmt.Println(demo6(5))
}
~~~
* 回調函數
~~~
package main
import "fmt"
type callback func(val, total int) int
func demo7(val int, callback callback) int {
if val > 0 {
return callback(val, 0)
} else {
return val
}
}
func addFunc(val int, total int) int {
if val > 0 {
return addFunc(val-1, total+val)
} else {
return total
}
}
func main() {
fmt.Println(demo7(5, addFunc))
}
~~~
> ### 官方建議官方建議寫法(給返回值定義一個名稱)
~~~
func Add(num1, num2 int) (num3 int) {
num3 = num1 + num2
return
}
~~~
> ### 閉包作用域
~~~
package main
import (
"fmt"
)
func main() {
number := make([]func(), 3)
//閉包可以直接使用外部的變量
//輸出 333
for i := 0; i < 3; i++ {
number[i] = func() {
fmt.Println(i)
}
}
//閉包函數的變量,后面調用閉包函數的變量
//全局變量 = 變量的最后一個值
//局部變量 = 當前值
/* 輸出 0 1 2
for i := 0; i < 3; i++ {
j := i
number[i] = func() {
fmt.Println(j)
}
}
*/
/* 輸出 333
j := 3
for i := 0; i < 3; i++ {
number[i] = func() {
fmt.Println(j)
}
}
*/
/* 輸出0 1 2
for i := 0; i < 3; i++ {
number[i] = Number(i)
}
*/
/*
for i := 0; i < 3; i++ {
number[i] = func() {
fmt.Println(i)
}
number[i]()
}
*/
for _, v := range number {
v()
}
}
func Number(i int) func() {
return func() {
fmt.Println(i)
}
}
~~~
> ### 相關閱讀
* [閉包函數介紹](http://www.cnblogs.com/leoin2012/p/3978979.html)
- 第一序 入門教程(一)
- 1.1環境配置
- 1.1 環境配置(補充:Linux下安裝)
- 1.1 環境配置(補充:線上部署)
- 1.2 開發工具GoLand
- 1.3 準備工作
- 1.4 第一個應用程序 Hello World
- 1.4 補充 go get github 超時
- 第二序 入門教程(二)
- 2.1 語法結構
- 2.2 常量, 變量
- 2.2.1 命名規則
- 2.2.2 變量
- 2.2.2 變量(補充:類型推斷的好處)
- 2.2.2 變量(補充:泛型)
- 2.2.3 常量
- 2.2.4 iota
- 2.2.5 Unicode字符編碼
- 2.2.6 GBK 轉 UTF8
- 2.3 條件語句
- 2.3.1 判斷語句 if
- 2.3.2 選擇語句 switch
- 2.3.3 循環語句 for
- 2.3.4 遍歷 range
- 2.3.5 跳轉語句 goto, break, continue
- 2.3.6 for 和 for range區別
- 2.4 數組, 切片, 集合, 通道
- 2.4.1 make, len, cap, new, nil
- 2.4.1 make, len, cap, new, nil (補充:nil)
- 2.4.2 數組 array
- 2.4.3.1 切片 slice - 1
- 2.4.3.2 切片 slice - 2
- 2.4.3.3 slice list ring
- 2.4.4 集合 map
- 2.4.5 goroutine
- 2.4.6 channel
- 2.5 函數, 結構, 方法, 接口
- 2.5.1 函數 function
- 2.5.2 結構 struct
- 2.5.3 方法 method
- 2.5.4 接口 interface
- 2.5.5 Go是面向對象的語言嗎?
- 2.5.6 json序列化和反序列化
- 2.5.7 T和指針T
- 2.6 defer, panic, recover
- 2.6.1 defer
- 2.6.2 painc, recover
- 2.7 指針
- 2.7 指針(補充: 可尋址和不可尋址)
- 2.8 反射
- 第三序 相關閱讀
- 3.1 相關閱讀1
- 3.2 相關閱讀2
- 3.3 相關閱讀3
- 第四序 性能分析和調試工具
- 4.1 pprof工具介紹
- 4.2 CPU信息采集
- 4.3 Heap信息采集
- 4.4 Http信息采集
- 4.5 單元測試(功能測試)
- 4.6 基準測試(壓力測試/性能測試)
- 4.7 示例測試(example)
- 4.8 gdb調試
- 第五序 網絡編程
- 5.1 http請求和響應
- 5.2 socket
- 5.2.1 概念
- 5.2.2 服務端
- 5.2.3 客戶端
- 5.3 WebSocket
- 5.3.1 第一版
- 5.3.1.1 服務端
- 5.3.1.2 客戶端
- 5.3.1.3 相關閱讀
- 5.3.2 服務端
- 5.3.3 客戶端
- 5.3.4 nginx配置
- 5.3.5 修改版
- 5.3.5.1 草稿 - 1
- 5.3.5.2 草稿 - 2
- 5.3.5.3 草稿 - 3
- 5.3.5.4 服務端
- 5.3.5.5 客戶端
- 5.4 打印客戶端頭部信息
- 第六序 算法
- 6.1 查找
- 6.1.1 二分查找
- 6.2 排序
- 6.2.1 交換排序 - 冒泡排序
- 6.2.2 插入排序 - 直接插入排序
- 6.2.3 插入排序 - 希爾排序
- 6.2.4 交換排序 - 快速排序
- 6.3 算法求解應用
- 第七序 微服務
- 7.1 相關閱讀
- 7.2 gRPC
- 7.2.1 準備工作
- 7.2.2 編譯.proto文件
- 7.2.3 gRPC服務端
- 7.2.4 gRPC客戶端
- 7.3 micro/micro
- 7.3.1 服務發現
- 7.3.2 安裝consul
- 7.3.3 準備工作
- 7.3.4 服務端
- 7.3.5 客戶端
- 7.3.6 默認的服務發現
- 7.3.7 文檔閱讀
- 7.4 protobuf序列化
- 第八序 Web
- 8.1 視圖模板
- 8.1.1 main.go
- 8.1.2 login.html
- 8.2 原生留言板
- 8.2.1 原生sql
- 8.2.1.1 main.go
- 8.2.1.2 view
- 8.2.1.2.1 index.html
- 8.2.1.2.2 create.html
- 8.2.2 sqlx
- 8.3 Gin框架
- 第九序 數據庫
- 9.0 資料收集
- 9.1 Redis數據庫 (gomodule/redigo)
- 9.1.1 介紹
- 9.1.2 消息隊列
- 9.2 Redis數據庫(go-redis/redis)
- 第十序 日記
- 10.1 SimplePanic
- 10.2 第一版日記庫
- 10.2.1 winnielog
- 10.2.2 使用
- 第十一序 中間鍵
- 11.0 資料收集
- 11.1 NSQ
- 11.2 zookeeper
- 11.3 kafka
- 第十二序 加密
- 12.1 Token
- 12.2 SHA1
- 2.3 RSA + AES
- 第十三序 分布式鎖
- 第十四序 標準庫練習
- container/list
- 鏈表
- container/ring
- 環形鏈表
- context
- flag (獲取命令行參數)
- io
- strconv
- sync
- 為什么需要鎖?
- 互斥鎖
- 讀寫鎖
- 條件變量
- 計數器
- 并發安全字典
- 自制并發安全字典
- 官方并發安全字典
- 連接池
- sync/atomic
- 原子操作
- 第十五序 其它內容
- 文件讀寫
- 工作池
- 第十六序 相關閱讀