Golang学习之---Golang的函数、包、错误处理机制、函数参数传递方式、变量(三)

一、函数

1、函数的基本语法

2、函数的调用过程

  • 上面的堆和栈都是逻辑空间,从上图可以得知:
  • (1)在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身的处理让这个新的空间和其他栈的空间区分开来
  • (2)每个函数对应的栈中,数据空间是独立的,不会混淆
  • (3)当一个函数调用完毕后,编译器会自动销毁这个函数对应的栈空间。

3、函数的递归调用

在数据结构中,递归是一个重要的知识。
一个函数在函数体内又调用了本身,我们称为递归调用。

1)、示例一及分析图:
输出结果:n=2 n=2 n=3

2)、示例二及分析图:
输出结果:n=2

3)、递归调用的总结:

  • 函数递归需要遵守的重要原则:
  • 1、执行一个函数时,就会创建一个新的受保护的独立空间(新函数栈)
  • 2、函数的局部变量是独立的,不会相互影响
  • 3、递归必须向退出递归的条件逼近,否则就是无限递归了
  • 4、当一个函数执行完成或者遇到return,就会返回。遵守:谁调用就将结果返回给谁。同时当函数执行完毕或者返回后,该函数本身也会被系统销毁

4、函数的使用注意事项

  • (5)基本类型和数组默认都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。在Java里面,数组是引用传递。

  • (6)如果形参是以值传递的方式的引用类型,我们想要修改原值,怎么操作?这时需要把该值的地址传进去&,函数内以指针的方式操作变量。从效果上看类似引用传递。

    注意:此时test2里的n1和main里的n1有不同的地址。因为是存在于不同的栈空间的。调用函数时,会为函数新开辟一个栈空间。类似于下图,n1和n1存在于不同的栈空间:
  • (7)Go函数不支持函数重载(它是以其他方式实现的)

5、init函数

当全局变量、init函数、main函数同时存在,且引入的utils也存在时,执行流程是什么呢?

6、匿名函数

匿名函数可以定义在函数内部,如main函数内部。

7、闭包

定义:闭包就是一个函数与其相关的引用环境组合的一个整体
简单来说,就是:闭包=return 匿名函数+引用的变量(变量只会初始化一次) 组合的整体
案例一:

案例二:

8、时间和日期函数 import time

9、随机数math.rand

10、内置函数

内置函数,也叫内建函数。就是程序本身定义好的一些函数,我们可以拿来直接使用,不需要导入包
查看文档 buildin模块

常用的内置函数:

  • 1、len函数,用来求长度,比如string、数组、切片、map、channel
    func len(v Type) int:内建函数len返回 v 的长度,取决于具体类型:...
  • 2、new函数,用来分配内存,主要用来分配值类型,比如int,float32...返回结果是指针类型

    上面代码对应的内存分析图:
  • 3、make函数,用来分配内存,主要用来分配引用类型,比如chan,map,slice...

二、包

1、包的使用注意事项

  • (1)在给一个文件打包时,该包对应一个文件夹。比如这里的utils文件夹对应的包名是utils
    文件的包名和文件所在的文件夹名一致,一般为小写字母。
    如果文件的包名和文件所在的文件夹名不一致,可以吗?
  • (3)函数名或变量名大写,才能被其他包访问到,类似于其他语言中的public
  • (4)访问其他包的函数或变量,其语法是:包名.函数名() 包名.变量名
  • (5)如果包名比较长,Go支持给包取别名,如main3.go
    调用:包的别名.函数名() 包的别名.变量名 // 注意:取别名后,原来的包名就不能用了
  • (6)同一包下,不能有相同的函数名和全局变量名
  • (7)如果需要编译成一个可执行文件,需要将这个包名声明为main,即package main.语法规范就这样
    如果你写一个库,包名可以自定义

三、错误处理机制

  • (1)Go语言追求简洁优雅,所以不支持传统的try...catch...finally这种处理
  • (2)Go中引入的处理方式为:defer, panic, recover
  • (3)使用场景:Go中可以手动抛出一个panic的异常,然后在defer中通过recover捕获这个异常,后续流程正常处理。

2、自定义错误

  • Go支持自定义错误,使用errors.New和panic内置函数
  • (1)errors.New("错误说明")会返回一个error类型的值,表示一个错误。import errors
  • (2)panic内置函数,接收一个interface{}类型的值(可以是任何值)作为参数。可以接收error类型的变量,输出错误信息,并退出程序

 四、函数参数传递方式(底层原理图)

1、两种方式:值传递和引用传递

值类型参数默认就是值传递,引用类型参数默认就是引用传递。

2、区别与联系

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

3、使用特点,和Java对比



五、变量


注意:

  • 1、相同名称的两个变量可以同时存在不同的作用域中,理解成不同的两个变量就行了。
  • 2、:= 不能定义全局变量
    如:age := 12 // 定义为全局变量报错。因为:等价于 var age int 和 age = 12。 age = 12是赋值语句,赋值语句不能写在函数体外

六、常量

用const定义 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值