golang学习笔记9:函数参数与返回值

栏目: Go · 发布时间: 5年前

内容简介:Go 默认使用按值传递来传递参数,也就是传递参数的副本。函数接收参数副本之后,在使用变量的过程中可能对副本的值进行更改,但不会影响到原来的变量,比如 Function(arg1)。如果你希望函数可以直接修改参数的值,而不是对参数的副本进行操作,你需要将参数的地址(变量名前面添加&符号,比如 &variable)传递给函数,这就是按引用传递,比如 Function(&arg1),此时传递给函数的是一个指针。如果传递给函数的是一个指针,指针的值(一个地址)会被复制,但指针的值所指向的地址上的值不会被复制;我们

按值传递和按引用传递

Go 默认使用按值传递来传递参数,也就是传递参数的副本。函数接收参数副本之后,在使用变量的过程中可能对副本的值进行更改,但不会影响到原来的变量,比如 Function(arg1)。

如果你希望函数可以直接修改参数的值,而不是对参数的副本进行操作,你需要将参数的地址(变量名前面添加&符号,比如 &variable)传递给函数,这就是按引用传递,比如 Function(&arg1),此时传递给函数的是一个指针。如果传递给函数的是一个指针,指针的值(一个地址)会被复制,但指针的值所指向的地址上的值不会被复制;我们可以通过这个指针的值来修改这个值所指向的地址上的值。(译者注:指针也是变量类型,有自己的地址和值,通常指针的值指向一个变量的地址。所以,按引用传递也是按值传递。)

几乎在任何情况下,传递指针(一个32位或者64位的值)的消耗都比传递副本来得少。

在函数调用时,像切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型都是默认使用引用传递(即使没有显式的指出指针)。

传递变长参数

如果函数的最后一个参数是采用 ...type 的形式,那么这个函数就可以处理一个变长的参数,这个长度可以为 0,这样的函数称为变参函数。

func myFunc(a, b, arg ...int) {}

这个函数接受一个类似某个类型的 slice 的参数 ,该参数可以通过for 循环结构迭代。

示例函数和调用:

func Greeting(prefix string, who ...string)
Greeting("hello:", "Joe", "Anna", "Eileen")

在 Greeting 函数中,变量 who 的值为 []string{"Joe", "Anna", "Eileen"}。

如果参数被存储在一个数组 arr 中,则可以通过 arr... 的形式来传递参数调用变参函数。

defer 和追踪

关键字 defer 允许我们推迟到函数返回之后(或任意位置执行 return 语句之后)一刻才执行某个语句或函数(为什么要在返回之后才执行这些语句?因为 return 语句同样可以包含一些操作,而不是单纯地返回某个值)。关键字 defer 的用法类似于面向对象编程语言 Java 和 C# 的 finally 语句块,它一般用于释放某些已分配的资源。

package main

import"fmt"

func main(){

function1()

}

func function1(){

fmt.Printf("In function1 at the top\n")

defer function2()

fmt.Printf("In function1 at the bottom!\n")

}

func function2(){

fmt.Printf("function2: Deferred until the end of the calling function!")

}

输出:

In Function1 at the topIn Function1 at the bottom!
Function2: Deferred until the end of the calling function!

当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出):

func f(){

for i :=0; i <5; i++ {

defer fmt.Printf("%d ", i)

} }

上面的代码将会输出:4 3 2 1 0。

将函数作为参数

package main

import("fmt")

func main()

{    callback(1, Add)   }

func Add(a, b int){

fmt.Printf("The sum of %d and %d is: %d\n", a, b, a+b)}

func callback(yint, f func(int,int)){

f(y,2)// this becomes Add(1, 2)

}

闭包

当我们不希望给函数起名字的时候,可以使用匿名函数,例如:func(x, y int) int { return x + y }。

这样的一个函数不能够独立存在(编译器会返回错误:non-declaration statement outside function body),但可以被赋值于某个变量,即保存函数的地址到变量中:fplus := func(x, y int) int { return x + y },然后通过变量名对函数进行调用:fplus(3,4)。

当然,也可以直接对匿名函数进行调用:func(x, y int) int { return x + y } (3, 4)。

golang学习笔记9:函数参数与返回值

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

惡血

惡血

[美] 约翰·凯瑞鲁 / 林锦慧 / 商業周刊 / 2018-9-20 / NT$430

--新創神話!?揭露3000億獨創醫療科技的超完美騙局-- 她被譽為女版賈伯斯、《富比世》全球最年輕的創業女富豪, 如何用「一滴血」顛覆血液檢測、翻轉醫療產業? 一項即將改變你我健康的醫療檢測新科技, 而它的技術來自--謊言! ◎即將改編成電影,由奧斯卡影后珍妮佛‧勞倫斯(Jennifer Lawrence)主演 ◎榮登《紐約時報》、《出版人週刊》暢銷榜 ......一起来看看 《惡血》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试