zoukankan      html  css  js  c++  java
  • Go的函数

    Go的函数

    一、函数的定义

    函数要定义在main函数的外面,无所谓前后。

    1、函数的基本格式

    // 不带返回值的函数
    func关键字 函数名(参数1 类型,参数2 类型,...){
    	函数体内容代码
    }
    
    // 带一个返回值的函数
    func关键字 函数名(参数1 类型,参数2 类型) 返回值类型 {
    	函数体内容代码
    }
    
    // 带多个返回值的函数
    func关键字 函数名(参数1 类型,参数2 类型) (返回值类型1,返回值类型2...) {
    	函数体内容代码
    }
    
    func main() {
    	test(66)
    }
    func test(a int) {
    	fmt.Println(a)
    }
    func t3(a,b int) int {
    	return a+b
    }
    

    2、函数的参数

    Go中函数的参数只有位置参数一种,没有关键字参数。

    如果有参数的类型相同,可以省略多余的类型关键字。

    func关键字 函数名(参数1,参数2 类型,。。。){
    	函数体内容代码
    }
    
    func main() {
        test(66,88)
        t2(1,2,"ok")
    }
    
    func test(a ,b int) {  // a,b都是int
    	fmt.Println(a+b)
    }  // 154
    
    func t2(a,b int,c string)  {  // a,b是int,c是string
    	fmt.Println(a+b,c)
    }  // 3 ok
    
    

    2.1 函数传参的特点:copy传值

    go语言中函数传参,都是copy传递。不管是值类型还是引用类型。都会copy一份,传进这个函数。

    如果是值类型的变量,传进函数后被修改,则不会影响被copy的变量。因为已经是不同的变量了。

    但如果是引用类型的变量,传进函数后被修改,是会影响到其他的引用这个地址的变量的。因为直接将这个地址的值修改了。

    Python的不同之处:

    Python参数传递统一使用的是引用传递方式。

    但Python对象分为可变对象(list,dict,set等)和不可变对象(number,string,tuple等)。

    当传递的参数是可变对象的引用时,因为可变对象的值可以修改,因此可以通过修改参数值而修改原对象。

    当传递的参数是不可变对象的引用时,虽然传递的是引用,参数变量和原变量都指向同一内存地址,但是由于Python做了处理使不可变对象无法修改,所以参数的修改不会影响原对象,而是重新开辟了一块地址放这个值。

    3、函数的返回值

    需要指定返回值类型是什么。

    声明位置在参数与函数代码块之间。

    如果有多个返回值,需要用小括号将返回值类型包起来。

    而且返回几个值,就必须用几个值来接收。不像Python可以用一个变量来接收多个返回值。

    如果不想接收参数,可以用下划线顶替。但在go中,下划线真的就是不接收,不像Python,下划线也是一个变量。

    func main() {
    	var r3 int = t3(1,2)
    	fmt.Println(r3)
        
        var r4,r5 int= t4(2,1)
    	fmt.Println(r4,r5)
    }
    
    func t3(a,b int) int {
    	return a+b
    }  // 3
    
    func t4(a,b int) (int,int) {
    	return a+b,a-b
    }  // 3 1
    

    4、可变长参数

    ...可以用来接收任意长度的参数。相当于Python中的*

    func main() {
    	t5(1,2,3,4,5,6,7)
    }
    
    func t5(a ...int)  {
    	fmt.Println(a)
    }  // [1 2 3 4 5 6 7] 生成一个切片
    

    二、函数的类型

    函数的类型包含函数的参数,返回值。

    var a func()
    var b func(a,b int)
    var c func(a,b int)int
    var d func(a,b int)(int,string)
    

    1、给函数的类型重命名

    语法:type 类型名称 函数类型

    也可以给其他类型重命名。

    func main() {
    	var s Myfunc = t8(1,2)
    	s(2)
    }
    
    type Myfunc  func(a int)int
    
    // func test(x,y int) func(z int)int {
    func t8(x,y int) Myfunc {
    	//只是一个内层函数
    	a:= func(z int)int {
    		fmt.Println(x+y+z)
    		return x+y+z
    	}
    	return a
    }  
    
    >>>:5
    

    三、匿名函数

    1、匿名函数的定义

    GO中,匿名函数只能定义在函数的内部。

    func t6()  { 
    	func () {  // 匿名函数
    		fmt.Println("ok")
    	}()
    }  
    

    2、匿名函数的执行

    // 方法一、直接加括号执行
    func main() {
    	t6()
    }
    
    func t6()  {
    	func () {
    		fmt.Println("ok")
    	}()
    }  // ok 
    
    // 方法二、用变量接收
    var a = func(a int) {
        fmt.Println("匿名函数")
    }
    fmt.Printf("%T",a) // func(int)
    a(1)
    

    四、闭包函数

    1、闭包的概念

    1. 定义在函数内部
    2. 对外部作用域有引用(引用外部变量)

    2、闭包函数的定义

    /* 这就不是闭包,因为没有引用外部变量
    func test() func() {
    	//只是一个内层函数
    	a:= func() {
    		fmt.Printf("我是内层函数")
    	}
    	return a
    }
    */
    
    // 闭包函数:引用了外部的变量
    func main() {
        var s Myfunc = t8(1,2)
        s(2)  // 5
    }
    
    type Myfunc  func(a int)int
    
    // func test(x,y int) func(z int)int {
    func t8(x,y int) Myfunc {
    	a:= func(z int)int {
    		fmt.Println(x+y+z)
    		return x+y+z
    	}
    	return a
    } 
    
  • 相关阅读:
    HDU 3829 Cat VS Dog (最大独立集)【二分图匹配】
    POJ 2594 Treasure Exploration (Floyd+最小路径覆盖)
    HDU 1054 Strategic Game (最小点覆盖)【二分图匹配】
    HDU 4185 Oil Skimming 【最大匹配】
    HDU 2389 Rain on your Parade 最大匹配(模板题)【HK算法】
    HDU 1281 棋盘游戏 (枚举+最大匹配)
    HDU 1045 Fire Net 【二分图匹配】
    POJ 1904 King's Quest (强连通分量+完美匹配)
    HDU 4635 Strongly connected (强连通分量+缩点)
    POJ 2631 Roads in the North (模板题)(树的直径)
  • 原文地址:https://www.cnblogs.com/bowendown/p/12595076.html
Copyright © 2011-2022 走看看