Golang函数

一.函数

    1.为完成某一功能的程序指令的集合,称为函数。在Go中,函数分为:自定义函数和系统函数

    2.基本语法:

       func 函数名 (形参列表)(返回值类型列表){

                  执行语句......

                  return 返回值列表

                        }

           (1)形参列表:表示函数的输入

           (2)函数中的语句:表示为了实现某一功能代码块

           (3)函数可以有返回值,也可以没有

案例:

        

二.包

     1.包的本质实际上就是创建不同的文件夹,来存放程序文件

       基本概念:go的每一个文件都属于一个包的,也就是说go是以包的形式来管理文件和项目目录                         结构的。

      原理图:

        

  2.作用:(1)区分相同名字的函数、变量标识符等

                (2)当程序文件很多时,可以很好管理项目

                (3)控制函数、变量等访问范围,即作用域

  3.相关说明:(1)打包基本语法

                            package 包的名字

                    (2)引入包的基本语法

                             import  " 路径 "

案例:

 细节说明:(1)在给一个文件打包时,该包对应一个文件夹,比如这里的utils文件夹对应的包名就是                       utils,文件的包名通常和文件所在的文件夹名一致,一般为小写字母。

                (2)当一个文件要使用其它包函数或变量时,需要先引入对应的包 import  "包名"

                (3)package指令在文件第一行,然后是import指令

                (4)在import包时,路径从$PATH的src下开始,不用带src,编译器会自动从src下开始引入

                (5)为了让其他包的文件,可以访问到本包的函数,则该函数名的首字母大写,类似其它语                 言的public,这样才能垮包访问。比如utils.go   

                (6)在访问其他包函数时,语法是:包名.函数名 

              

                 (7)如果包名较长,Go支持给包取别名,但取别名后原来的包就不能,例如:原来调用方式为utils.Cal,取别名为utul后,调用方式为util.Cal

                

               (8)同一个包里面不能有相同的函数(也不能有相同的全局变量名)

               (9)如果你要编译成一个可执行程序文件,就需要将这个包声明为main,即package main,这个是语法规范,如果你写的只是一个库,包名可以自定义

三.函数-调用机制

  函数-调用过程图:

    说明(1):在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身的处理让这个新的           空间和其他栈的空间区分开来

           (2)在每个函数对应的栈中,数据空间是空间的,不会混淆

           (3)当一个函数调用完毕或者使用完毕后,程序会销毁这个数对应的栈空间

 return语句

 GO函数支持返回多个值,这一点是其它编程语言没有的

       func 函数名(形参列表) (返回值类型列表){

          语句

          return返回值列表

           }

说明(1)如果返回多个值时,在接收时,希望忽略某个返回值,则使用_符号表示站位忽略

       (2)如果返回值只有一个,(返回值类型列表) 可以不写()

 

 三.函数-递归调用

      一个函数在函数体内又调用了函数本身,我们称为递归调用

  

 

 函数递归需要遵守的重要原则:

    (1)执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)

    (2)函数的局部变量是独立的,不会相互影响

    (3)递归必须向退出递归的条件逼近,否则就是无限递归

    (4)当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁。同时当      函数执行完毕或者返回时,该函数本身也会被系统销毁。

案例:1.用递归方式求斐波那契数。

            

        2.求函数值,已知f(1)=3;f(n)=2*f(n-1)+1,用递归方式求出f(n)的值:

            

      3.猴子吃桃问题,有一堆桃子,猴子每天吃其中的一半并多吃一个,第十天时就剩一个了。

             

 函数的注意事项:

     1.函数的形参列表可以是多个,返回值列表也可是多个.

     2.形参列表和返回值列表的数据类型可以是值类型和引用类型.

     3.函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其他包文件使用,类似public,首字母小写,只能被本包文件使用,其他包文件不能使用,类似private。

     4.函数中的变量是局部的,函数外不生效

     5.基本数据类型和数组默认是值传递的,即进行值拷贝。在函数类修改,不会影响到原来的值。

     6.如果希望函数类的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量

    7.Go函数不支持重载    //会报错,会报函数重复定义

    8.在Go中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了,通过该变量可以对函数调用。

                            

    9.函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用

                  

   10.为了简化数据类型定义,Go支持自定义数据类型

        基本语法:type 自定义数据类型名 数据类型   // 相当于一个别名

        案例:type mylnt int //这时mytln就等价 int 来使用了

        案例:type mySum func (int,int) int //这时mySum就等价一个函数类型func(int,int) int

        //在Go中 myint和int虽然都是int类型,但是go认为这两者是两个类型,不一样,赋值的时候会 报错,要转换

                               

   11.支持对函数返回值命名

        

       

  12.使用_标识符,忽略返回值

       

    13.Go支持可变参数

        

      说明:

      (1)args是slice,通过args[index] 可以访问到各个值.

      (2)案例演示:编写一个函数sum,可以求出1到多个int的和

      (3)如果一个函数的形参列表中有可变参数,则可变参数需要放在形参列表最后

           

案例:编写一个函数swap(n1 *int,n2 *int)可以交换n1和n2 的值

        

       

四.init函数

    每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用,也就是说init会在main函数前被调用,通常可以在init函数中完成初始化工作。

    注意:(1)如果一个文件同时包含全局变量定义,init函数和main函数,则执行的流程是变量定义->init函数->main函数

            (2)init函数最主要的作用,就是完成一些初始化的工作,比如下面的案例:

 

五.匿名函数

  1.Go支持匿名函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也       可以实现多次调用

  2.匿名函数使用方法:

     (1)在定义匿名函数时就直接调用,这种方式匿名函数就只能调用一次

                       

     (2)将匿名函数赋给一个变量(函数变量),再通过该变量来调用匿名函数

                      

   3.全局匿名函数:

          如果将匿名函数赋给一个全局变量,那么这个匿名函数,就成为一个全局匿名函数,可以在        程序有效

                     

六.闭包

    1.闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)

               

 对上面代码的说明和总结

     (1)AddUpper 是一个函数,返回的数据类型是fun (int)  int

     (2)闭包的说明

                      

            返回的是一个匿名函数,但这个匿名函数引用到函数外的n,因此这个匿名函数就和n形成一个整体,构成闭包。

     (3)闭包是类,函数是操作,n是字段

     (4)当我们反复的调用f函数时,因为n是初始化一次,因此每调用一次就进行累加.

 2.闭包实践:

    编写一个程序,具体要求如下

    (1)编写一个函数makeSuffix(suffix string)可以接收一个文件后缀名(比如.jpg),并返回一个闭包

    (2)调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg),则返回 文件名.jpg,如果已经有.jpg后缀,则返回原文件名

    (3)要求使用闭包的方式完成

    (4)string.HasSuffix

             

代码说明:

 1.返回的匿名函数和 makeSuffix(suffix string)的suffix变量组合成一个闭包,因为返回的函数引用到suffix这个变量

七.函数中-defer

     在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等),为了在函数执行完毕后,及时的释放资源,Go的设计者提供defer(延时机制)

        

    defer的细节说明:

    (1)当go执行到一个defer时,不会立即执行defer后的语句,而是将defer后的语句压入到一个栈            中,然后继续执行函数下一个语句

    (2)当函数执行完毕后,在从defer栈中,依次从栈顶取出语句执行

    (3)在defer将语句放入到栈时,也会将相关的值拷贝同时入栈

八.函数参数的传递方式

    1.值传递和引用传递

        ps:不管是值传递还是引用传递,传递给函数大的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递还是地址的拷贝,一般来说地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低

    2.值类型和引用类型

      1.值类型:基本数据类型int系列,float系列,bool,string、数组和结构体struct

      2.引用类型:指针、slice切片、map、管道chan、interface等都是引用类型

九.变量作用域

    1.函数内部声明/定义的变量叫局部变量,作用域仅限于函数内部

    2.函数外部声明/定义的变量叫全局变量,作用域在整个包都有效,如果其首字母为大写,则作用域在整个程序有效

   3.如果变量是在一个代码块,比如for/if中,那么这个变量的作用域就在该代码块

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老实憨厚的腾锅锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值