(5-2)函数:函数的参数

5.2  函数的参数

Go语言中的函数可以有参数和返回值,参数可以是任意类型,包括基本类型、复合类型(例如结构体和数组)、接口类型和函数类型。在函数声明时,参数的类型和名称被指定,并且可以有多个参数,它们以逗号分隔。可以将Go语言函数的参数分为两种类型:值传递和引用传递。

5.2.1  值传递

在Go语言中,值传递是指将参数的值复制到函数的形参中,函数对形参的任何修改不会影响原始变量的值。在值传递中,函数参数传递的是变量的值,而不是变量的地址。这意味着函数对参数值的修改不会影响原始变量的值。

例如,下面是一个带有两个参数的函数例子,它使用值传递方式。

func add(a, b int) int {
    return a + b
}

在上面的函数add()中,a和b是两个整型参数,它们被声明为int类型,并且在函数调用时传递两个整型值。这个函数将这两个参数相加,并返回它们的和。

再看下面的例子,演示了使用值传递的过程。

func main() {
    x := 1
    fmt.Println("Before foo call, x is", x)
    foo(x)
    fmt.Println("After foo call, x is", x)
}

func foo(a int) {
    fmt.Println("Inside foo, before incrementing a, a is", a)
    a++
    fmt.Println("Inside foo, after incrementing a, a is", a)
}

在上述代码中,定义了一个 x 变量并将其设置为1。然后我们调用函数foo(),并传递 x 变量的值。在函数foo()内部,我们打印出传递进来的参数值,并将其增加1。最后,在函数main()中再次打印 x 的值。执行后会输出:

Before foo call, x is 1
Inside foo, before incrementing a, a is 1
Inside foo, after incrementing a, a is 2
After foo call, x is 1

实例5-3:交换两个数的值(源码路径:Go-codes\5\swap.go

实例文件swap.go的具体实现代码如下所示。

package main
import "fmt"
func main() {
	/* 定义变量 */
	var a int = 100
	var b int = 200

	fmt.Printf("交换前 a 的值为 : %d\n", a )
	fmt.Printf("交换前 b 的值为 : %d\n", b )

	/* 通过调用函数来交换值 */
	swap(a, b)

	fmt.Printf("交换后 a 的值 : %d\n", a )
	fmt.Printf("交换后 b 的值 : %d\n", b )
}

/* 定义相互交换值的函数 */
func swap(x, y int) int {
	var temp int

	temp = x /* 保存 x 的值 */
	x = y    /* 将 y 值赋给 x */
	y = temp /* 将 temp 值赋给 y*/

	return temp;
}

在上述代码中,使用值传递方式来调用函数swap()。执行后会输出:

交换前 a 的值为 : 100

交换前 b 的值为 : 200

交换后 a 的值 : 100

交换后 b 的值 : 200

注意:值传递的优点是简单、安全,因为不会影响原始变量的值。但缺点是如果传递的变量很大,那么复制变量的值可能会带来显著的性能损失。

5.2.2  引用传递

在Go语言中,引用传递是指将参数的引用(指针)复制到函数的形参中,函数对形参的修改会影响原始变量的值。在引用传递中,将参数的地址作为实参传递给函数,函数内部可以直接通过这个地址对参数进行操作,操作的结果将影响到原始的实参。

例如同样是交换两个参数的值,下面的代码(源码路径:Go-codes\5\swap02.go)是使用引用传递调用函数swap()实现的。

package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int= 200

   fmt.Printf("交换前,a 的值 : %d\n", a )
   fmt.Printf("交换前,b 的值 : %d\n", b )

   /* 调用 swap() 函数
   * &a 指向 a 指针,a 变量的地址
   * &b 指向 b 指针,b 变量的地址
   */
   swap(&a, &b)

   fmt.Printf("交换后,a 的值 : %d\n", a )
   fmt.Printf("交换后,b 的值 : %d\n", b )
}

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* 保存 x 地址上的值 */
   *x = *y      /* 将 y 值赋给 x */
   *y = temp    /* 将 temp 值赋给 y */
}

执行后会输出:

交换前,a 的值 : 100
交换前,b 的值 : 200
交换后,a 的值 : 200
交换后,b 的值 : 100

再看下面的代码,在函数main()中定义了一个整型变量 x,并将其初始化为 10。在调用函数changeX()时,将 x 的地址传递给了函数,函数内部通过 *px 来访问 x 的值,并将其改为 20。最后在函数main()中输出 x 的值,可以看到 x 的值已经被成功修改。

注意:引用传递只对可寻址的变量起作用,因为需要传递变量的地址。如果一个变量不可寻址,比如一个常量或者一个表达式的结果,那么无法使用引用传递的方式将其传递给函数。

5.2.3  可变参数

Go语言支持可变参数,可以使用不定数量的参数来调用函数。这种特性在有些情况下非常有用,比如我们想向函数传递一个变长的列表,但是列表的长度不确定。在Go语言中,可变参数是通过在参数类型前加上省略符“...”来定义的,例如:

func myFunc(args ...int) {
    //函数体
}

在上述代码中,args是一个整数类型的切片,可以传递任意数量的整数参数给这个函数。在函数内部,可以使用for range语法来遍历可变参数,例如:

func myFunc(args ...int) {
    for index, value := range args {
        fmt.Printf("args[%d]=%d\n", index, value)
    }
}

在调用这个函数时,可以传递任意数量的整数参数,例如:

myFunc(1, 2, 3, 4, 5)
myFunc(10, 20, 30)
myFunc()

在这些调用中,函数myFunc()接收到的参数分别是一个包含五个整数的切片,一个包含三个整数的切片,以及一个空的切片。

5.2.4  将数组作为函数的参数

在Go语言中,可以将数组作为函数的参数传递,也可以使用切片(slice)作为参数传递。在函数参数中传递数组,可以通过指定数组的长度或使用“...”语法来实现。

实例5-4:计算数组中元素的平均值(源码路径:Go-codes\5\arry.go

实例文件arry.go的具体实现代码如下所示。

// 计算数组元素的平均值
func average(nums [5]float64) float64 {
	var sum float64 = 0
	for _, num := range nums {
		sum += num
	}
	return sum / float64(len(nums))
}

func main() {
	// 定义一个数组
	nums := [5]float64{98, 72, 84, 56, 69}

	// 调用 average 函数并输出结果
	fmt.Println(average(nums))
}

在上述代码中,函数average()的参数nums是一个长度为5的float64类型的数组。该函数计算数组元素的平均值并返回结果。在main函数中,定义一个包含5个float64类型元素的数组nums,并调用函数average()并传递该数组作为参数。执行后会输出:

75.8

5.2.5  将切片作为函数的参数

在 Go 语言中,切片也可以作为函数的参数传递,和数组不同的是,切片的长度是动态的,因此切片传递的实参和形参在函数调用时不需要考虑切片的长度。

实例5-5:计算数组中元素的和(源码路径:Go-codes\5\sum.go

实例文件sum.go的具体实现代码如下所示。

func sum(slice []int) int {
    result := 0
    for _, v := range slice {
        result += v
    }
    return result
}
func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println("Sum of", slice, "is", sum(slice))
}

在上述代码中,函数 sum()接收一个 []int 类型的切片作为参数,使用 for 循环遍历切片中的每一个元素并将其相加,最后返回结果。在函数main()中,创建了一个切片 slice,并将其作为参数传递给函数sum()。执行后会输出:

Sum of [1 2 3 4 5] is 15

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农三叔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值