Go教程函数

Posted 玖五二七

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go教程函数相关的知识,希望对你有一定的参考价值。

函数是由一行或多行代码组成的集合, 你可以在程序中其它位置调用它.

Go允许我们定义自己的函数

func Foo()
  fmt.Println("hi")

函数声明以关键字func开头,后跟函数名,一对()来接受可选的参数,然后是包含函数代码的

一旦声明了一个函数你就可以在程序的其他地方调用它.只需要输入它的名字即可.

当执行foo时,我们没有在函数名之前加包名.在调用当前包中定义的函数时,是不需要指定包名的.

函数命名规则:

  • 必须以字母开头,后跟数量和字母
  • 名称以大写开头的函数是可导出的,并可以在当前包外部使用.
  • 包含多单词的名称应该使用驼峰命名方法

声明函数参数

如果希望对函数的调用包含参数,则需要声明一个或多个参数.参数是函数的局部变量.其值是在调用函数时设置.

func Foo1(a string, b int)    // a,b为形式上的参数
  fmt.Printf("%s %d \\n", a, b)

可以在()中间声明多个参数,并用逗号隔开.与变量一样,你需要为声明的每个参数提供一个名称+类型

如果函数定义了参数的,需要在调用它的时候传入与参数个数和类型都匹配的一组实际参数.每个参数都被设置为对应形式参数值的副本.然后这些参数值在函数的代码中被使用.

func Test() 
  fmt.Println("test function")
  Foo()
  Foo1("hello", 1)  // 这里传入的是**实际参数**

函数返回值

如果我们要在函数中计算结果并返回,需要在函数的声明后面加上返回值的类型

func Sum(a int, b int) int 
  return a + b


func Test() 
  fmt.Println("test function")
  Foo()
  Foo1("hello", 1)
  sum := Sum(1, 2)
  fmt.Println("sum 1, 2 = ", sum)


声明多个返回值

我们把Sum函数改造一下,让它更加安全,增加一个错误类型的返回值

要声明多个返回值,需要将函数类型放在函数声明的**第二组()**中,用逗号分隔开来.

当只有一个返回值时,()是可选的,不是必须的.但是有多个返回值时,必须要圆括号

func Sum(a int, b int) (int, error) 
  if b > 10 
    return 0, fmt.Errorf("b must below 10")
  
  return a + b, nil


func Test() 
  fmt.Println("test function")
  Foo()
  Foo1("hello", 1)
  sum, err := Sum(1, 20)
  if err != nil 
    fmt.Println("sum err  ", err)
   else 
    fmt.Println("sum 1, 2 = ", sum)
  


以上就是对函数错误值的处理了.在Sum函数中,第二个返回值用来指示错误

始终处理错误

在golang中没有trycatch,也没有except之类的语法糖,每个一错误都需要手动捕捉.

所以go的建议是对所有函数都进行错误处理,以保证程序运行的稳定性.

我们应该始终检查函数的返回值是否存在错误,以及如何处理这个错误.

函数形参接收实参的副本

Go是一种值传递的语言,函数形参从函数调用中接收实参的副本

对于函数中不必修改参数值的调用没有任何问题,但是如果需要修改形参值的时候就会有些问题.函数只能修改形参中的副本,而不是原始值.而这个副本的作用域仅仅在函数内部.因此函数内部所作的修改在函数外部是看不见的.

我们演示一段代码来说明这个问题

func AutoAdd(a int) 
  a++
  fmt.Println("Auto add a = ", a)


func Test() 
  a := 1
  AutoAdd(a)
  fmt.Println("a = ", a)

结果如下

Auto add a =  2
a =  1

通过指针修复AutoAdd函数

通过指针,我们可以达到修改原始参数的目的.

func AutoAdd(a *int) 
  *a++
  fmt.Println("Auto add a = ", *a)

func Test() 
  a := 1
  AutoAdd(&a)
  fmt.Println("a = ", a)


结果如我们所预期的

Auto add a =  2
a =  2

a的原始值已经发生了改变

可变长函数参数

可变长的函数参数可以以多种参数个数来调用.为了让函数的参数可变长,在函数声明中最后参数类型前使用省略号…

func MyFunc(param1 int, param2 ...string)   // 省略号+类型代表可变长参数

可变长参数函数的最后一个参数接收一个切片类型的变长参数.这个切片可以补当成普通切牌来处理.

package variable

import "fmt"

func ManyInts(n ...int) 
  fmt.Println(n)


main.go

package main

import "function/variable"

func main() 
  variable.ManyInts(1)
  variable.ManyInts(1, 2, 3)
  variable.ManyInts()


以下是打印的结果,如果什么都不传,则默认是一个空切片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vFYwrhaW-1648255634344)(https://secure2.wostatic.cn/static/okxZefyFyNmY5azn3VKvg2/image.png)]

函数也可以接收一个或多个变长和非变长参数.即一个函数可以忽略变长参数,其中的非可变长参数无法忽略,如果忽略的话会导致编译失败.仅仅函数定义中的最后一个参数可以是可变长参数,不能把它放到必需参数之前

func Mix(n int, f float32, s ...string) 
  fmt.Println(n, f, s)

main.go

package main

import "function/variable"

func main() 
  variable.Mix(1, 2)
  variable.Mix(1, 2, "hello", "world")

IndexOf函数接收一个整型值,然后返回它在给定切片中的第一个下标位置.没有返回-1

variable/a.go

func IndexOf(n int, number ...int) int 
  for index, value := range number 
    if n == value 
      return index
    
  
  return -1

main.go

package main

import "function/variable"

func main() 
  fmt.Println("index of 1 in [2, 3, 4, 5, 1]", variable.IndexOf(1, 2, 3, 4, 5, 1))
  fmt.Println("index of 1 in [2, 3, 4, 5, 7]", variable.IndexOf(1, 2, 3, 4, 5, 7))

向可参数变函传递切片

我们把上面的程序改一下,变以直接传切片

func main() 
  fmt.Println("index of 1 in [2, 3, 4, 5, 1]", variable.IndexOf(1, 2, 3, 4, 5, 1))
  fmt.Println("index of 1 in [2, 3, 4, 5, 7]", variable.IndexOf(1, 2, 3, 4, 5, 7))
  slice := []int1, 2, 3, 4, 5
  fmt.Println("index of 1 in ", slice, variable.IndexOf(1, slice...))


最后那个地方大家注意一下,在slice后面加…省略号就可以了.我在VSCode中安装了rich go插件是会自动补齐的.

Go中推荐使用for … range访问切片和映射

以上是关于Go教程函数的主要内容,如果未能解决你的问题,请参考以下文章

go的匿名函数结尾圆括号的含义

Go 入门 - 包,函数和变量

javascript篇-----函数

英语一般疑问句后跟称谓,标点符号怎么

函数 函数式编程

JS函数