Go之函数

一、函数基本使用

  一)函数概述

  1、函数定义

  对特定的功能进行提取,形成一个代码片段

  2、函数的作用

  提高代码的复用性,减少代码的冗余,代码的维护性也提高了

  3、函数中间的关系

  函数与函数是并列关系,所以定义的函数不能放到main函数中

  4、基本语法
func 函数名 (形参列表) (返回值类型列表) {
  执行语句
  return + 返回值列表  
}
  函数名
  • 遵循标识符命名规范:见明知意 addNum
  • 首字母不能是数字
  • 首字母大些 该函数可以被本包文件和其他包文件使用(类似public)
  • 首字母小写只能被本包文件使用,其他包文件不能使用(类似private)
  形参列表
  • 形参列表:可以一个参数,也可以是n个参数,可以是0个参数
  • 形式参数参数:作用,接收外来的数据
  • 实际参数:实际传入的数据
func calc(num1 int, num2 int) int {
    var sum int = 0
    sum += num1
    sum += num2
    return sum
}

func main() {
    sum := calc(10, 20)
    fmt.Println(sum)
}

  返回值类型列表

  返回值类型列表:返回的返回值对应的类型应该写在这个列表中

  • 返回0个:若没有返回值,那么返回值类型什么都不写就可以
func calc(num1 int, num2 int) { //若返回值类型就一个的话,那么()是可以省略不写的

    var sum int = 0
    sum += num1
    sum += num2
    //return sum
    fmt.Println(sum)
}

func main() {
    //功能
    //调用函数
    calc(10, 20)
    //fmt.Println(sum)
}
  • 返回1个:若返回值类型就一个的话,那么()是可以省略不写的
func calc(num1 int, num2 int) int { //若返回值类型就一个的话,那么()是可以省略不写的

    var sum int = 0
    sum += num1
    sum += num2
    return sum
    //fmt.Println(sum)
}

func main() {
    //功能
    //调用函数
    //calc(10, 20)
    sum := calc(10,20)
    fmt.Println(sum)
}

  • 返回多个
func calc2(num1 int, num2 int) (int, int) { //若返回值类型就一个的话,那么()是可以省略不写的

    var sum int = 0
    sum += num1
    sum += num2
    var result int = num1 - num2

    return sum, result
    //fmt.Println(sum)
}

func main() {
    //功能
    //调用函数
    //calc(10, 20)
    //sum := calc(10, 20)
    //fmt.Println(sum)
    sum1, result1 := calc2(30, 20)
    fmt.Println("sum1 is ", sum1)
    fmt.Println("result1 is ", result1)
}

  若有返回值不想接受,那么可以利用_进行忽略

  二)函数实战

  1、函数实现:两个数交换(内存分析)
  错误示例:下面的方式不能实现数字交换,执行交换函数前后结果相同

  单纯的值传递对函数外面的值没有影响

//自定义函数:交换两个数
func exchangeNum(num1 int, num2 int) {
    var t int
    t = num1
    num1 = num2
    num2 = t
}

func main() {
    //调用函数
    var num1 int = 10
    var num2 int = 20
    fmt.Printf("The two numbers before exchange: num1 = %v,num2 = %v\n", num1, num2)
    exchangeNum(num1, num2)
    fmt.Printf("The two numbers after exchange: num1 = %v,num2 = %v\n", num1, num2)
}

  

  正确做法:通过使用指针来进行数据的交换
//自定义函数:交换两个数
func exchangeNum(num1 *int, num2 *int) {
    t := *num1
    *num1 = *num2
    *num2 = t
}

func main() {
    //调用函数
    num1 := 10
    num2 := 20
    fmt.Printf("The two numbers before exchange: num1 = %v,num2 = %v\n", num1, num2)
    exchangeNum(&num1, &num2)
    fmt.Printf("The two numbers after exchange: num1 = %v,num2 = %v\n", num1, num2)
}

  输出结果如下

The two numbers before exchange: num1 = 10,num2 = 20
The two numbers after exchange: num1 = 20,num2 = 10

  2、golang函数不支持重载

  函数重载:不支持同时定义两个名字一样的函数

   3、支持可变参数(若希望函数带有可变数量的参数)
//定义一个函数,函数的参数为可变参数,参数的数量可变
//args...int 可以传入任意多(0-n)个数量的int类型的数据
func test(args ...int) {
    //函数内部处理可变参数时,将可变参数当做切片来处理
    //遍历可变函数:
    for i := 0; i < len(args); i++ {
        fmt.Println(args[i])
    }
}

func main() {
    test()
    fmt.Println("-------------------------------------------")
    test(8)
    fmt.Println("-------------------------------------------")
    test(1, 16, 168, 1688)
}

  输出结果

-------------------------------------------
8
-------------------------------------------
1
16
168
1688

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

  

  5、以值传递方式的数据类型,若希望在函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量

  6、函数也是一种数据类型,可以赋值给一个变量,则此变量就成为一个函数类型的变量了。通过改变量可以对函数调用。
package main

import "fmt"

//定义一个函数
func test(num int) {
    fmt.Println(num)
}

func main() {
    //函数也是一种数据类型,可以赋值给一个变量
    a := test //变量就是一个函数类型的变量
    fmt.Printf("a的类型是: %T, test函数的类型是: %T \n", a, test)
    //a的类型是:func(int),test的函数类型是func(int)

    //通过该变量可以对函数调用
    a(10)
}

  7、函数既然是一种数据类型,因此函数可以作为形参,并且可以调用
package main

import "fmt"

//定义一个函数
func test(num int) {
    fmt.Println(num)
}

func test02(num1 int, num2 float32, testFunc func(int)) {
    fmt.Println("-----test02")
}
func main() {
    //函数也是一种数据类型,可以赋值给一个变量
    a := test //变量就是一个函数类型的变量
    fmt.Printf("a的类型是: %T, test函数的类型是: %T \n", a, test)
    //a的类型是:func(int),test的函数类型是func(int)

    //通过该变量可以对函数调用
    a(10) //等价于 test(10)
    //调用test02函数
    test02(10, 3.19, test)
    test02(10, 3.19, a)
}

  8、为了简化数据类型定义,go支持自定义数据类型

  基本语法:type 自定义数据类型名 数据类型

  自定义数据类型相当于起个别名

  实战1

type myInt int ————>myInt就等价于int

  

func main() {
    //自定义数据类型:(相当于起别名)给int类型起了个别名叫myInt类型
    type myInt int
    var num1 myInt = 30
    fmt.Println("num1", num1)
    var num2 int = 30
    //num2 = num1  //虽然是别名,但是在go中编译识别时,还是认为myInt和int不是一种数据类型
    num2 = int(num1)
    fmt.Println("num2", num2)
}

  实战2

type mySum func(int, int) int ————>此时mySum就等价一个函数类型func(int, int) int

type myFunc func(int)
func test03(num1 int, num2 float32, testFunc myFunc) {
    fmt.Println("-----test03")
}

  9、支持函数返回值命名

  传统写法要求:返回值和返回值的类型对应,顺序不能差

func test04(num1 int, num2 int) (int, int) {
    result01 := num1 + num2
    result02 := num1 - num2
    return result01, result02
}

  升级写法:对函数返回值命名,里面顺序就无所谓了,顺序不用对应

//定义一个函数:求两个数的和、差
func test05(num1 int, num2 int) (sum int, sub int) {
    result02 := num1 - num2
    result01 := num1 + num2

    fmt.Println(result01, result02)
    return result02, result01
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值