go六:函数

一、函数的语法格式:

二、变量的作用域

package main

import "fmt"

//声明全局变量
var a int = 7
var b int = 9

func main() {
    //声明局部变量
    a, b, c := 10, 20, 0
    fmt.Printf("main()函数中a=%d\n", a) //10
    fmt.Printf("main()函数中b=%d\n", b)  //20
    fmt.Printf("main()函数中c=%d\n=====\n", c)   //0
    c = sum(a, b)
    cc := sum2(a, b)
    fmt.Printf("main()函数中c=%d\n", cc) // 33
}
func sum(a, b int) int {
    a++
    b += 2
    c := a + b
    fmt.Printf("main()函数中a=%d\n", a) //11
    fmt.Printf("main()函数中b=%d\n", b)  //22
    fmt.Printf("main()函数中c=%d\n=====\n", c) // 33
    return c
}
func sum2(a, b int) (c int) {
    a++
    b += 2
    c = a + b
    fmt.Printf("main()函数中a=%d\n", a) //11
    fmt.Printf("main()函数中b=%d\n", b)  //22
    fmt.Printf("main()函数中c=%d\n", c) // 33
    return
}
main()函数中a=10
main()函数中b=20
main()函数中c=0
=====
main()函数中a=11
main()函数中b=22
main()函数中c=33
=====
main()函数中a=11
main()函数中b=22
main()函数中c=33
main()函数中c=33

 三、函数变量:函数作为值  

package main

import (
    "strings"
    "fmt"
)

func main() {
    str := "abcdEFGH"
    //result := processLetter(str)
    //fmt.Printf("%T, %v", result, result)
    fmt.Println(StringToCase(str, processLetter))
    fmt.Println(StringToCase2(str, processLetter))
}
//实现大小写字母奇数偶数交替
func processLetter(str string) string {
    result := ""
    for i, value := range str {
        if i %2 == 0 {
            result += strings.ToUpper(string(value))
        } else {
            result += strings.ToLower(string(value))
        }
    }
    return result
}
//函数作为变量传递:使用普通的方法
func StringToCase(str string, myfunc func(string) string) string {
    return myfunc(str)
}
//函数作为变量传递:使用type自定义类型
type caseFunc func(string) string
func StringToCase2(str string, myfunc caseFunc) string {
    return myfunc(str)
}
package main

import "fmt"

func main() {
    arr := []int {2, 5, 10, 20 ,22, 25, 23, 22, 22, 21}
    fmt.Println("sline = ", arr)
    //获取切片中的奇数无素
    odd := Filter(arr, isOdd)
    fmt.Println(odd)
}
//判断无数是偶数
func isEven(num int) bool {
    if num % 2 == 0 {
        return true
    }
    return false
}
//判断无数是奇数
func isOdd(num int) bool {
    if num % 2 == 0 {
        return false
    }
    return true
}
//使用type定义自定义类型
type myFunc func(int) bool
//根据函数来处理切片,实现奇数偶数分组,返回新的切片
func Filter(arr []int, fn myFunc) []int {
    var result []int
    for _, value := range arr {
        if fn(value) {
            result = append(result, value)
        }
    }
    return result
}

 

 四、匿名函数 

五、闭包 

 示例:实现一个累加器

如果使用普通函数定义一个累加器,普通函数中的保存累加数的sum变量,是局部变量,每次调用普通函数,都需要定义它。结果是sum每次都被初始化为0,不能实现累加

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Printf("i=%d\t", i)
        fmt.Println(add(i))
    }
}
//实现计数的函数
func add(num int) int {
    sum := 0
    sum += num
    return sum
}
i=0    0
i=1    1
i=2    2
i=3    3
i=4    4

 要想使得变量sum,在重复调用以上函数时,不要每次都初始化sum。必须将sum的值保存起来,使得重复调用时,sum不要被初始化。这需要用闭包来实现。

package main

import "fmt"

func main() {
    res := adder()
    fmt.Printf("%T \n", res)
    for i := 0; i < 5; i++ {
        fmt.Printf("i=%d\t", i)
        fmt.Println(res(i))
    }
}
//实现计数的闭包函数
func adder() func(int) int {
    sum := 0
    res := func(num int) int {
        sum += num
        return sum
    }
    return res
}
func(int) int 
i=0    0
i=1    1
i=2    3
i=3    6
i=4    10

 示例:计数器

package main

import "fmt"

func main() {
    res := Counter()  //返回一个函数
    fmt.Printf("res: %T\n", res)
    fmt.Println("res: ", res)
    fmt.Printf("res()的类型: %T\n", res())  //1
    fmt.Printf("res(): %d\n", res())  //2
    fmt.Printf("res(): %d\n=======\n", res())  //3

    res2 := Counter()  //返回一个函数
    fmt.Printf("res(): %d\n", res2())  //1
    fmt.Printf("res(): %d\n", res2())  //2
    fmt.Printf("res(): %d\n", res2())  //3
}
//闭包函数,实现计数器功能
//闭包函数必须:有返回值,返回的是一个匿名函数;闭包函数内部,嵌套函数外部要有一个要保护的局部变量
func Counter() func() int {
    i := 0
    res := func() int {
        i++
        return i
    }
    fmt.Println("Count内部: ", res)
    return res  //返回一个函数
}
Count内部:  0x48d680
res: func() int
res:  0x48d680
res()的类型: int
res(): 2
res(): 3
=======
Count内部:  0x48d680
res(): 1
res(): 2
res(): 3

 

示例:闭包也是匿名函数的计数器

package main

import "fmt"

func main() {
    res := func() (func() int) {
        i := 0
        return func() int {
            i++
            return i
        }
    }()
    fmt.Println(res)
    fmt.Println(res())  //1
    fmt.Println(res()) //2
}
0x48b6b0
1
2

 

六、函数的可变参数

package main

import "fmt"

func main() {
    //1.传n个参数
    fmt.Println(AddSum(1,2,3,4,5,6))
    //2.传0个参数
    fmt.Println(AddSum())
    //3.传切片作为参数
    arr := []int{3, 4, 5, 6, 34, 36, 69}
    fmt.Println(AddSum(arr...))
}
func AddSum(nums ...int) (sum int) {
    fmt.Printf("%T \n", nums)
    for _, value := range nums {
        sum += value
    }
    return
}
[]int 
21
[]int 
0
[]int 
157
package main

import "fmt"

func main() {
    //1.传n个成绩的用法
    sum, avg, count, name := GetScore("jason", 90, 80.2, 55, 65)
    fmt.Printf("学生%s,%d门课程,总成绩为%.2f,平均成线为%.2f", name, count, sum, avg)
    fmt.Println()
    //2.传一个切片的用法
    scores := []float64{90, 80.2, 55, 65, 100, 70}
    sum, avg, count, name = GetScore("jerry", scores...)
    fmt.Printf("学生%s,%d门课程,总成绩为%.2f,平均成线为%.2f", name, count, sum, avg)
}
func GetScore(name string, scores ... float64) (sum, avg float64, count int, user_name string) {
    for _, value := range scores {
        sum += value
        count++
    }
    avg = sum/float64(count)
    user_name = name
    return
}
//学生jason,4门课程,总成绩为290.20,平均成线为72.55
//学生jerry,6门课程,总成绩为460.20,平均成线为76.70

七、递归函数

package main

import "fmt"

func main() {
    fmt.Println(getMultiple(10))
    fmt.Println(factorial(10))
}

//通过循环方式实现阶乘
func getMultiple(num int) (result int) {
    result = 1
    for i := 1; i <= num; i++ {
        result *= i
    }
    return result
}
//通过递归方式实现 阶乘
func factorial(n int) int {
    if n == 0 {
        return 1
    }
    return n * factorial(n-1)
}

 

posted on 2018-03-28 08:20  myworldworld  阅读(151)  评论(0)    收藏  举报

导航