zoukankan      html  css  js  c++  java
  • Go 函数编程

    函数的声明

    在 Go 语言中,函数声明通用语法如下:

    func functionname(parametername type) returntype {  
        // 函数体(具体实现的功能)
    }

    函数的声明以关键词 func 开始,后面紧跟自定义的函数名 functionname (函数名)。函数的参数列表定义在 ( 和 ) 之间,返回值的类型则定义在之后的 returntype (返回值类型)处。声明一个参数的语法采用 参数名 参数类型 的方式,任意多个参数采用类似 (parameter1 type, parameter2 type) 即(参数1 参数1的类型,参数2 参数2的类型)的形式指定。之后包含在 { 和 } 之间的代码,就是函数体。

    函数中的参数列表和返回值并非是必须的,所以下面这个函数的声明也是有效的

    func functionname() {  
        // 译注: 表示这个函数不需要输入参数,且没有返回值
    } 

    注意:go语言中函数参数不支持默认值。

    示例程序

    package main
    
    import "fmt"
    
    
    //传入单个参数
    func functionname1(parametername int){
    	fmt.Printf("参数:%d
    ",parametername);
    }
    
    //传入单个参数,单个返回值
    func functionname2(parametername int) int{
    	fmt.Printf("参数:%d
    ",parametername);
    	return parametername*parametername;
    }
    
    //传入多个参数
    func functionname3(parametername1 int,parametername2 int){
    	fmt.Printf("参数1:%d
    ",parametername1);
    	fmt.Printf("参数2:%d
    ",parametername2);
    }
    
    //传入多个参数,多个返回值
    func functionname4(parametername1 int,parametername2 int)(int,int){
    	fmt.Printf("参数1:%d
    ",parametername1);
    	fmt.Printf("参数2:%d
    ",parametername2);
    	return parametername1*parametername2,parametername1+parametername2;
    }
    
    
    
    func main(){
    	a := 1;
    	b := 2;
    	functionname1(a);
    	functionname2(a);
    	functionname3(a,b);
    	functionname4(a,b);
    }
    

    函数实现可变参数

    上面举的例子,参数个数都是固定的,这很好理解 ,指定什么类型的参数就传入什么类型的变量,数量上,不能多一个,也不能少一个。(好像没有可选参数)。

    在 Python 中我们可以使用 *args 和 **kw ,还实现可变参数的函数。

    可变参数分为几种:

    • 多个类型一致的参数

    • 多个类型不一致的参数

    多个类型一致的参数

    首先是多个类型一致的参数。

    这边定义一个可以对多个数值进行求和的函数,

    使用 ...int,表示一个元素为int类型的切片,用来接收调用者传入的参数。

    // 使用 ...类型,表示一个元素为int类型的切片
    func sum(args ...int) int {
        var sum int
        for _, v := range args {
            sum += v
        }
        return sum
    }
    func main() {
        fmt.Println(sum(1, 2, 3))
    }
    
    // output: 6

    其中 ... 是 Go 语言为了方便程序员写代码而实现的语法糖,如果该函数下会多个类型的函数,这个语法糖必须得是最后一个参数。

    同时这个语法糖,只能在定义函数时使用。

    多个类型不一致的参数

    上面那个例子中,我们的参数类型都是 int,如果你希望传多个参数且这些参数的类型都不一样,可以指定类型为 ...interface{},然后再遍历。

    比如下面这段代码,是Go语言标准库中 fmt.Printf() 的函数原型:

    import "fmt"
    func MyPrintf(args ...interface{}) {
        for _, arg := range args {
            switch arg.(type) {
                case int:
                    fmt.Println(arg, "is an int value.")
                case string:
                    fmt.Println(arg, "is a string value.")
                case int64:
                    fmt.Println(arg, "is an int64 value.")
                default:
                    fmt.Println(arg, "is an unknown type.")
            }
        }
    }
    
    func main() {
        var v1 int = 1
        var v2 int64 = 234
        var v3 string = "hello"
        var v4 float32 = 1.234
        MyPrintf(v1, v2, v3, v4)
    }

    在某些情况下,我们需要定义一个参数个数可变的函数,具体传入几个参数,由调用者自己决定,但不管传入几个参数,函数都能够处理。

    比如这边实现一个累加

    func myfunc(args ...int) {
        for _, arg := range args {
            fmt.Println(arg)
        }
    }
    

     

    返回值

    隐式返回

    func rectProps(length, width float64)(area, perimeter float64) {  
        area = length * width
        perimeter = (length + width) * 2
        return // 不需要明确指定返回值,默认返回 area, perimeter 的值
    }

    请注意, 函数中的 return 语句没有显式返回任何值。由于 area 和 perimeter 在函数声明中指定为返回值, 因此当遇到 return 语句时, 它们将自动从函数返回。

     多返回值

    Go 支持一个函数返回多个值

    多个可变参数函数传递参数

    上面提到了可以使用 ...  来接收多个参数,除此之外,它还有一个用法,就是用来解序列,将函数的可变参数(一个切片)一个一个取出来,传递给另一个可变参数的函数,而不是传递可变参数变量本身。
    
    同样这个用法,也只能在给函数传递参数里使用。
    
    例子如下:
    import "fmt"
    
    func sum(args ...int) int {
        var result int
        for _, v := range args {
            result += v
        }
        return result
    }
    
    func Sum(args ...int) int {
        // 利用 ... 来解序列
        result := sum(args...)
        return result
    }
    func main() {
        fmt.Println(sum(1, 2, 3))
    }
    

      

    函数导出与首字母大写

    以程序导入gotest/even包为例
    package main
    
    import (
        "even"
        "fmt"
    )
    
    func main() {
        i:=even.I
        fmt.Printf("Is %d even? %v
    ", i, even.Even(i))
    }
    
    package even
    
    var I int = 123
    
     func Even(i int) bool {
        return i%2==0
    }
    
    func odd(i int) bool {
        return i%2!=0
    }
    
    1.本地包 even 在这里导入;
    2. 官方 fmt 包导入;
    3.调用 even 包中的函数。访问一个包中的函数的语法是 <package>.Function(),变量 <package>.Var。
    在 Go 中,当变量或函数的首字母大写的时候,函数会被从包中导出(在包外部可见,或者说公有的),因此函数名是 Even。如果修改main.go 的第 10 行,使用未导出的函数 even.odd:
    fmt.Printf("Is %d even? %v
    ", i, even.odd(i))
    
    由于使用了私有的函数,会得到一个编译错误:
    main.go:10: cannot refer to unexported name even.odd
    
    概括来说:
     公有函数的名字以大写字母开头;
    私有函数的名字以小写字母开头。
    

    匿名函数的使用

    所谓匿名函数,就是没有名字的函数,它只有函数逻辑体,而没有函数名。

    定义的格式如下

    func(参数列表)(返回参数列表){
        函数体
    }
    // 第二个参数为函数
    func visit(list []int, f func(int)) {
        for _, v := range list {
            // 执行回调函数
            f(v)
        }
    }
    func main() {
        // 使用匿名函数直接做为参数,当作回调函数
        visit([]int{1, 2, 3, 4}, func(v int) {
            fmt.Println(v)
        })
    }
    

     

    空白符

    _ 在 Go 中被用作空白符,可以用作表示任何类型的任何值。

    我们继续以 rectProps 函数为例,该函数计算的是面积和周长。假使我们只需要计算面积,而并不关心周长的计算结果,该怎么调用这个函数呢?这时,空白符 _ 就上场了。

    下面的程序我们只用到了函数 rectProps 的一个返回值 area

    package main
    
    import (  
        "fmt"
    )
    
    func rectProps(length, width float64) (float64, float64) {  
        var area = length * width
        var perimeter = (length + width) * 2
        return area, perimeter
    }
    
    func main() {  
        area, _ := rectProps(10.8, 5.6) // 返回值周长被丢弃
        fmt.Printf("Area %f ", area)
    }

    运行这个程序

    在程序的 area, _ := rectProps(10.8, 5.6) 这一行,我们看到空白符 _ 用来跳过不要的计算结果。


    refer:
    『GCTT 出品』Go 系列教程 —— 6. 函数(Function)


  • 相关阅读:
    tornado学习
    pycharm使用技巧
    k8s排查问题利器-----kubectl debug
    linux的python3 环境配置
    flink入门学习
    jenkins deploy key的使用
    通过浏览器模拟网速慢,接口block等异常情况
    curl常用语法举例
    jmeter测试双向认证https接口
    一些开发的总结
  • 原文地址:https://www.cnblogs.com/-wenli/p/11780013.html
Copyright © 2011-2022 走看看