第三章 go语言

一、函数基础

  定义:有输入、有输出、用来执行一个指定任务的代码块

func 函数名(形参列表)(返回值列表){
    执行代码
    return 返回值列表
}

//无参数和返回值
func test(){
    fmt.Println("helloWorld")
}
func main(){
    test()
}

//函数的多返回值
func test(x,y int,z string) (int,string){
    //类型相同的相邻参数x,y参数类型可以合并
    //多返回值得用括号括起来
    n := x+y
    return n,z
}

//返回值进行命名
func test2(a,b int) (sum int,sub int) {
    sum = a+b
    sub = a-b
    return
}
func main(){
    sum,sub := test2(100,800)
    fmt.Println(sum,sub)
}

//可变参数
func test3(b ...int) int{
    sum :=0
    for i := 0;i<len(b);i++{
        sum = sum + b[i]
    }
    return sum
}
func main(){
    sum := test3(10,20)    //可以传任意个参数
    fmt.Printf("sum=%d\n"),sum)
}

二、函数defer语句

    定义:在一个函数中有defer语句时,只有到返回的时候才会执行,多个defer时执行顺序是从后往前,多用于资源脂肪,使用defer关闭资源

func test(){
    defer fmt.Println("Hello")
    fmt.Println("Parallel")
    fmt.Println("World")
)
//结果    Parallel  World  Hello

func test2(){
    defer fmt.Println("Hello")
    defer fmt.Println("Hello1")
    defer fmt.Println("Hello2")
    fmt.Println("Parallel")
    fmt.Println("World")
}
//结果    Parallel  World  Hello2  Hello1  Hello

fun test3(){
    for i:=0;i<5;i++{
        defer fmt.Println(i)
    }
}
//结果    4  3  2  1  0

func test4(){
    i := 0
    defer fmt.Println(i)
    i = 1000
    fmt.Println(i)
}
//结果    1000 0    当执行代码到defer时,参数已经传入,但是最后执行

三、内置函数

    close:主要用来关闭channel(管道)

    len:用来求长度(如:string,array,slice,map,channel)

    new:用来初始化int、struct,返回指针  var a = new(int):得到一个int类型的指针

    make:用来初始化channel,map,slice

    append:用来追加元素到slice

    panic和recover:用来做错误处理  

  变量作用域和可见性

//作用域:全局变量,在函数最外层
var a int = 100
func test(){
    fmt.Printf("a = %d\n",a)
}

//作用域:局部变量(1.函数内定义2.语句块内定义)
func add(a int,b int) int {
    var sum int = 0    //sum是局部变量
    if a>0{
        var c int = 100    //c是局部变量,只在if语句块有效
    }
}

//可见性:包内任何变量或函数都是能访问的,首字母大写是可以导出的,能够被其他包访问或调用,小写表示私有,不能被嗲用
package caic
var a int = 100
var A int = 200
func Add(a,b int) int{
    return a+b
}
func sub(a,b int) int{
    return a-b
}

package caic
func Test()int{
    return a
}    //包名相同,可以调用

package main
import ("fmt","caic")
func main(){
    var s1 int = 200
    var s2 int = 300
    sum := calc.Add(s1,s2)
    fmt.Printf("s1+s2=%d",sum)    //500
    fmt.Printf("caic.A=%d",caic.A)    //200
    fmt.Printf("caic.a=%d",caic.Test())
}    //可以调用caic包中的Add函数和Test函数还有大写的的变量

四、匿名函数

//函数是一种类型,因此可以定义一个函数类型的变量
func add(a,b int) int{
    return a + b
}
func testFunc1(){
    f1:=add
    fmt.Printf("type of f1 = %T\n",f1)    //打印变量用%T
    sum := f1(2,5)    //函数类型的变量
    fmt.Printf("sum=%d\n",sum)
}
func main(){
    testFunc1()
}

//匿名函数,没有命名的函数
func testFunc2(){
    f1 := func(a,b int) int{    //匿名函数
        return a+b
    }
    fmt.Printf("type of f1=%T\n",f1)
    sum := f1(2,5)
    fmt.Printf("sum = %d\n",sum)
}
funt main(){
    testFunc2()
}

//defer使用匿名函数
func testFunc3(){    
    defer func(){
        fmt.Printf("defer i=%d\n",i)    //100
    }()
    i = 100
    fmt.Printf("i=%d\n",i)
}

//函数作为一个参数
func add(a,b int) int{
    return a+b
}
func sub(a,b int) int{
    return a-b
}
func calc(a,b int,op func(int,int)int)int{
    return op(a,b)
}
func testDefer5(){
    sum := calc(100,300,add)
    sub := calc(100,300,sub)
    fmt.Printf("sum-%d sub-%d\n",sum,sub)
}

五、函数闭包

    定义:一个函数和与其相关的引用环境组合而成的实体(匿名函数嵌套,闭包是外部函数嵌套内部函数,内部函数引用外部函数的变量,外部函数用完变量后,被内部函数引用并保留下来,作为自由变量使用,就是闭包)

func Adder() func(int) int{
    var x int
    return func(d int) int{
        x += d
        return x
    }
}
func testClosure1(){
    f:= Adder()
    ret := f(1)
    fmt.Printf("ret=%d\n",ret)    //1
    ret = f(20)
    fmt.Printf("ret%d\n",ret)    //21
    ret = f(300)
    fmt.Printf("ret=%d\n",ret)    //321
}

//test
func add(base int) func(int) int{
    return func (i int) int{
        base += i
        return base
    }
}
func testClosure1(){
    tmp1 := add(10)
    fmt.Println(tmp1(1),tmp1(2))
    tmp2 := add(100)
    fmt.println(tmp2(1),tmp2(2))
}

//test2
func test(suffix string) func(string) string{
    return func(name string) string{
        if !strings.HasSuffix(name,suffix){
            return name + suffix
        }
        return name
    }
}
func testClosure1(){
    func1 := test(".bmp")
    func2 := test(".jpg")
    fmt.Println(func1("test"))    //test.bmp
    fmt.Println(func2("test"))    //test.jpg
}

//test3
func calc(base int) (func(int) int,func(int) int) {
    add := func(i int) int{
        base += i
        return base
    }
    return add,sub
}
func testClosure1(){
    f1,f2 := calc(10)
    fmt.Println(f1(1),f2(2))    //11 9
    fmt.Println(f1(3), f2(4))    //12 8
    fmt.Println(f1(5), f2(6))    //13 7
    fmt.Println(f1(7), f2(8))    //14 6
}

//test4
func testClosure1(){
    for i:=0;i<5;i++{
        go func(){
            Fmt.Println(i)
        }()
    }
    time.Sleep(time.Second)
}
//输出    55555    有坑,每次i会赋值给函数中,但到5时才打印

//test5
func testClosure1(){
    for i:=0;i<5;i++{
        go func(index int) {
            fmt.Println(index)
        }(i)
    }
    time.Sleep(time.Second)
}
//输出    01234

  

  

猜你喜欢

转载自www.cnblogs.com/parallel-Y/p/11412602.html