美文网首页golang学习笔记
golang学习笔记9:函数参数与返回值

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

作者: 编程老司机 | 来源:发表于2018-10-21 00:00 被阅读52次

按值传递和按引用传递

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:函数参数与返回值

    按值传递和按引用传递 Go 默认使用按值传递来传递参数,也就是传递参数的副本。函数接收参数副本之后,在使用变量的过...

  • swift学习笔记(6)--- 函数

    1、函数的定义与调用 2、函数参数与返回值 无参数函数 多参数函数 无返回值函数 多重返回值函数 可选元组返回类型...

  • 7章 初始函数

    本章大纲 函数定义与调用 参数与返回值 内置函数 函数的定义与调用 函数的定义 函数的调用 参数与返回值 内置函数...

  • swift学习笔记 函数

    本文章是本人学习 swift 时的笔记,略简单 1、函数的定义与调用: 2、无参数函数 3、无返回值函数 虽说是无...

  • GO语言学习 - bytes 包

    转载来自于:Golang学习 - bytes 包 对于传入 []byte 的函数,都不会修改传入的参数,返回值要么...

  • Swift-函数

    函数的定义与调用 无参数函数,有返回值(返回值类型String) 多参数函数,有返回值(返回值类型String) ...

  • Golang函数

    函数 Golang函数特点 无需声明原型支持多返回值不定参数传参 也就是函数的参数个数不是固定的 但是后面的类型是...

  • Swift 3.0学习笔记_10_函数

    函数的定义与调用, 函数的参数与返回值, 函数参数标签和参数名称, 函数类型, 嵌套函数

  • 6_函数

    函数参数与返回值 无参数函数 多参数函数 无返回值函数 省略返回箭头(->)和返回类型。 注意严格上来说,虽然没有...

  • Day6 函数(Functions)

    本页包含内容:- 函数定义与调用- 函数参数与返回值- 函数参数标签和参数名称- 函数类型- 嵌套函数 ** 1、...

网友评论

    本文标题:golang学习笔记9:函数参数与返回值

    本文链接:https://www.haomeiwen.com/subject/bzevzftx.html