1. 程式人生 > >GO 學習筆記——第二天 / 函式,工程管理

GO 學習筆記——第二天 / 函式,工程管理

1.自定義函式

package main

import "fmt"

//虛擬碼
func main() {
 TestFun(1, 2, 3, 4, 5, 6)
}

//無參無返回值
func TestFun() {
 fmt.Println("TestFun null")
}

//有參無返回值
func TestFun(a int, b int) {
 fmt.Println("TestFun a:", a, ",b:", b)
}

//不定引數列表
func TestFun(args ...int) {
 fmt.Println(len(args))
 for i := 0; i < len
(args); i++ { fmt.Println(args[i]) } //可以迭代 for i, data := range args { fmt.Println("i:", i, ":data:", data) } } //不定引數傳遞 func TestFun(args ...int) { //全部傳遞 test(args...) //指定從第2個元素開始傳遞 2:和 :2 的區別 test(args[2:]...) } func test(tmp ...int) { } //無參有返回值 func TestFun() (result string) { result =
"Hello World!" return result } //多個返回值 func TestFun() (int, int, int) { return 1, 2, 3 } //有參有返回值 func TestFun(a, b, int) (max, min, int) { if a > b { max = a min = b } else { max = b min = a } return max, min }

2.遞迴函式

  • 然而並沒有什麼卵用

3.函式型別

  • 主要體現多型思想
package main

import "fmt"

func main
() { var fTest FuncType fTest = Add c := fTest(1, 2) fmt.Println(c) } type FuncType func(int, int) int func Add(a, b int) int { return a + b }
  • 回撥函式
package main

import "fmt"

func main() {
 //c := Calu(1, 1, Add)
 c := Calu(10, 1, Jdd)
 fmt.Println(c)
}

type FuncType func(int, int) int

func Calu(a, b int, mTest FuncType) (result int) {
 result = mTest(a, b)
 return result
}

//實現加法
func Add(a, b int) int {
 return a + b
}

//實現減法
func Jdd(a, b int) int {
 return a - b
}

//無限實現對應的函式

4.匿名函式與閉包

  • 匿名函式
package main

import "fmt"

func main() {

 a := 10
 str := "Hello"

 f1 := func() {
  fmt.Println("a:", a)
  fmt.Println("str:", str)
 }

 f1()

 type FuncType func()

 var f2 FuncType

 f2 = f1

 f2()

 //定義匿名函式同時呼叫
 func() {
  fmt.Println("a:", a)
  fmt.Println("str:", str)
 }()

 //帶引數的匿名函式
 f3 := func(i, j int) {
  fmt.Println("i:", i)
  fmt.Println("j:", j)
 }
 f3(1, 2)

 //帶引數的匿名函式同時呼叫
 func(i, j int) {
  fmt.Println("i:", i)
  fmt.Println("j:", j)
 }(10, 20)

 //有引數有返回值
 f4, f5 := func(i, j int) (max, min int) {
  if i > j {
   max = i
   min = j
  } else {
   max = j
   min = i
  }
  return max, min
 }(10, 20)

 fmt.Println("f4:", f4)
 fmt.Println("f5:", f5)
}
  • 閉包
    • 所謂閉包就是一個函式捕獲了和它同一作用域的常量和變數,這就意味著當閉包被呼叫的時候,不管在程式什麼地方呼叫,閉包能使用這些常量或者變數,他不關心這些捕獲了的常量和變數是否超出了作用域,所以只要閉包還在使用它,這些變數就會存在
package main

import "fmt"

func main() {

 a := 10
 str := "Hello"

 f1 := func() {
  fmt.Println("a:", a)
  fmt.Println("str:", str)
 }

 f1()

 type FuncType func()

 //宣告
 var f2 FuncType

 f2 = f1

 f2()

 //定義匿名函式同時呼叫
 func() {
  fmt.Println("a:", a)
  fmt.Println("str:", str)
 }()

 //帶引數的匿名函式
 f3 := func(i, j int) {
  fmt.Println("i:", i)
  fmt.Println("j:", j)
 }
 f3(1, 2)

 //帶引數的匿名函式同時呼叫
 func(i, j int) {
  fmt.Println("i:", i)
  fmt.Println("j:", j)
 }(10, 20)

 //有引數有返回值
 f4, f5 := func(i, j int) (max, min int) {
  if i > j {
   max = i
   min = j
  } else {
   max = j
   min = i
  }
  return max, min
 }(10, 20)

 fmt.Println("f4:", f4)
 fmt.Println("f5:", f5)

 fmt.Println("--------------")

 //傳統函式
 fmt.Println(Test())
 fmt.Println(Test())
 fmt.Println(Test())
 fmt.Println(Test())
 fmt.Println(Test())

 fmt.Println("--------------")

 //閉包的特性
 f := Test01()
 fmt.Println(f())
 fmt.Println(f())
 fmt.Println(f())
 fmt.Println(f())
 fmt.Println(f())
}

//傳統函式
func Test() int {
 //函式呼叫時才會分配空間
 var x int
 x++
 //函式呼叫完成後釋放
 return x * x
}

//閉包函式
func Test01() func() int {
 var x int
 return func() int {
  x++
  return x * x
 }
}

5.延遲呼叫defer

  • 在函式或者方法最後退出前呼叫
package main

import "fmt"

func main() {

 fmt.Println("1")
 //在函式結束前呼叫
 defer fmt.Println("2")
 fmt.Println("3")
 //輸出1 3 2
}
  • 如果一個函式中有多個defer,他會以後進先出的順序執行,並且不管函式發生什麼錯誤,都不會影響defer的執行
package main

import "fmt"

func main() {

 defer fmt.Println("1")
 defer fmt.Println("2")
 defer fmt.Println("3")

 //輸出 3 2 1
}
  • 和匿名函式的使用
package main

import "fmt"

func main() {

 a := 10
 b := 20

 defer func() {
  fmt.Println("a:", a, "b:", b)
 }()

 a = 11
 b = 21

 //輸出 11 21
}

6.獲取命令列引數

  • 藉助os包
package main

import "fmt"
import "os"

func main() {

 //接收使用者傳遞的引數
 list := os.Args
 //引數的個數
 n := len(list)
 fmt.Println("n:", n)
 //輸入 go run xx.go a b
 for i := 0; i < n; i++ {
  fmt.Println("list:", list[i])
 }
 //輸出  xx.go  a b
}

7.作用域

  • 定義在大括號裡為區域性變數,他的作用域就在括號內
  • 定義在大括號外的為全域性變數,他的作用域是全域性
  • 區域性變數和全域性變數同名的情況下優先區域性變數

8.工程管理

  • 導包
package main

//匯入 1
import "fmt"

//匯入 2
import (
 "fmt"
)

//匯入 3 不需要函式呼叫
import . "fmt"

//匯入 4 起別名
import put "fmt"

//匯入 5 忽略此包
import _ "fmt"

func main() {
 put.Println("Hello ")
}
  • go env 檢視GOPATH
  • 多檔案必須放在src
  • 設定GOPATH環境變數
  • 同一個目錄的包名必須一致
  • 同一個目錄呼叫別的檔案的函式直接呼叫即可
  • 不用目錄,包名不一樣
  • 呼叫不同包裡的函式,格式:包名.函式名
  • 首字母大寫才能供別人呼叫
package main

import (
 "calu"
 "fmt"
)

func main() {
 a := calu.Add(1, 1)
 fmt.Println("a:", a)
}
  • init函式
    • 匯入包會先執行包的init函式