go函数

shhnwangjian shhnwangjian     2022-09-16     610

关键词:

函数声明和注释

1、函数声明: func 函数名字 (参数列表)  [(返回值列表)] {}

 

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

2. 注释,两种注释,单行注释: // 和多行注释 /* */

3、 一个.go文件初始化,先执行全局变量,再执行init()函数,init()函数自动调用

4、多个包引用,如果引用顺序是main -> add -> test,初始化顺序:test.go的全局变量->test.go的init()->add全局变量->add.go的init()->main.go全局变量->main.go的init()

 

函数特点

  • 不支持重载,一个包不能有两个名字一样的函数
  • 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
  • 匿名函数
  • 多返回值

样例:

package main

import "fmt"

type op_func func(int, int) int

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

func sub(a, b int) int {
	return a - b
}

func operator(op op_func, a int, b int) int {
	return op(a, b)
}

func main() {
	c := add
	fmt.Println(c)
	sum := operator(c, 100, 200)
	fmt.Println(sum)

	var d op_func
	d = sub
	fmt.Println(d)
	sub := operator(d, 100, 200)
	fmt.Println(sub)
}

 

自定义函数

demo

package main

import "fmt"

type add_func func(int, int) int

func add(a, b int) int {
	return a + b
}
func operator(op add_func, a int, b int) int {
	//使⽤用传进来的函数,进⾏行行操作
	return op(a, b)
}
func main() {
	c := add
	fmt.Println(c)
	sum := operator(c, 100, 200)
	fmt.Println(sum)
}

 

函数参数传递方式

  • 值传递
  • 引用传递

注意:无论是值传递,还是引用传递,传递给函数的都是变量的副本。不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。

map、slice、chan、指针、interface默认以引用的方式传递。

 

命名返回值的名字

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

func calc(a, b int) (sum int, avg int) {
        sum = a + b
        avg = (a + b)/2
        return
}

 

_标识符,用来忽略返回值

func calc(a, b int) (sum int, avg int) {
        sum = a + b
        avg = (a + b) / 2
        return
}

func main() {
      sum, _ := calc(100, 200)
}

 

可变参数

  • 0个或多个参数
func add(arg…int) int {
}
  • 1个或多个参数
func add(a int, arg…int) int {
}
  • 2个或多个参数
func add(a int, b int, arg…int) int {
}

注意:其中arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数。

样例:

package main

import "fmt"

func add(a int, arg...int) int{
	var sum int = a
	for i := 0; i < len(arg); i ++ {
		sum += arg[i]
	}
	return sum
}

func add_string(a string, arg...string) (result string) {
	result = a
	for i := 0; i < len(arg); i ++ {
		result += arg[i]
	}
	return
}

func main() {
	sum := add(10, 1 , 2, 3)
	fmt.Println(sum)
	str := add_string("hello ", "world ", "wang")
	fmt.Println(str)
}

 

匿名函数

样例:

package main

import "fmt"

var(
	result = func(a1, b1 int) int{
		return a1 + b1
	}
)

func test(a, b int) int {
	result := func(a1, b1 int) int{
		return a1 + b1
	}(a, b)
	return  result
}

func test1(a, b int) int {
	result := func(a1, b1 int) int{
		return a1 + b1
	}
	return  result(a, b)
}

func main() {
	sum := test(10 , 20)
	fmt.Println(sum)
	sum1 := test1(1, 2)
	fmt.Println(sum1)
	fmt.Println(result(3,4))
}

 

defer用途

  • 当函数返回时,执行defer语句。因此,可以用来做资源清理
  • 多个defer语句,按先进后出的方式执行
  • defer语句中的变量,在defer声明时就决定了

样例:

package main

import "fmt"

func main() {
	var i int = 0
	defer fmt.Println(i)
	defer fmt.Println("second")
	i = 10
	fmt.Println(i)
}

说明:上面代码执行,先将defer压入栈中,当main函数执行完成后,再执行defer内容。多个defer语句,按先进后出的方式执行。同时defer语句的变量i声明时为0,所以结果也为0

使用场景举例:

1、关闭文件句柄

func read() {  
    //文件操作
    file := open(filename)
    defer file.Close()
}

2、锁资源释放

func read() {
    mc.Lock()
    defer mc.Unlock()
    // 其他操作
}

3、数据库连接释放

func read() {
    conn := openDatabase()
    defer conn.Close()
    //其他操作
}

 

内置函数

  • close:主要用来关闭channel
  • len:用来求长度,比如string、array、slice、map、channel
  • new:用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
  • make:用来分配内存,主要用来分配引用类型,比如chan、map、slice
  • append:用来追加元素到数组、slice中
  • panic和recover:用来做错误处理

new和make的区别

package main

import "fmt"

func test() {
	s1 := new([]int)
	fmt.Println(s1)

	s2 := make([]int, 10)
	fmt.Println(s2)

	*s1 = make([]int, 5)
	(*s1)[0] = 100
	s2[0] = 100
	fmt.Println(s1)
	return
}

func main() {
	test()
}

 

递归函数

函数调用自己,就叫做递归。

 

递归的设计原则

  • 一个大的问题能够分解成相似的小问题
  • 定义好出口条件

 

样例:

package main

import (
	"fmt"
	"time"
)

func recusive(n int) {
	fmt.Println("hello", n)
	time.Sleep(time.Second)
	if n > 10 {
		return
	}
	recusive(n + 1)
}

func factor(n int) int {
	if n == 1 {
		return 1
	}
	return factor(n-1) * n
}

func fab(n int) int {
	if n <= 1 {
		return 1
	}
	return fab(n-1) + fab(n-2)
}

func main() {
	//fmt.Println(factor(5))
	recusive(0)
	/*for i := 0; i < 10; i++ {
		fmt.Println(fab(i))
	}*/
}

 

闭包

一个函数和与其相关的引⽤用环境组合⽽而成的实体。

demo1:

func Adder() func(int) int {

	var x int
	f := func(i int) int {
		x = x + i
		return x
	}

	return f
}

func testClosure() {

	f1 := Adder()
	fmt.Println(f1(10))
	fmt.Println(f1(20))
	fmt.Println(f1(30))

	f2 := Adder()
	fmt.Println(f2(10))
	fmt.Println(f2(20))
	fmt.Println(f2(30))
}

 

demo2:

package main

import (
	"fmt"
	"strings"
)

func makeSuffixFunc(suffix string) func(string) string {
	return func(name string) string {
		if !strings.HasSuffix(name, suffix) {
			return name + suffix
		}
		return name
	}
}
func main() {
	bmp := makeSuffixFunc(".bmp")
	jpg := makeSuffixFunc(".jpg")
	fmt.Println(bmp("test"))
	fmt.Println(jpg("test"))
}

 

go函数

函数声明和注释1、函数声明:func函数名字(参数列表)(返回值列表){}2.注释,两种注释,单行注释://和多行注释/**/3、一个.go文件初始化,先执行全局变量,再执行init()函数,init()函数自动调用4、多个包引用,如果引用顺序是mai... 查看详情

go语言学习(二十)go语言递归函数

Go语言递归函数递归,就是在运行的过程中调用自己。语法格式如下:funcrecursion()recursion()/*函数调用自身*/funcmain()recursion()Go语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。递归函... 查看详情

go语言之函数方法

在Go语言中,函数和方法不太一样,有明确的概念区分。在其他语言中,比如Java,一般来说,函数就是方法,方法就是函数。但是在Go语言中,函数是指不属于任何结构体、类型的方法。也就是说,函数是没有接收者的;而方法... 查看详情

go语言学习笔记—基础—函数:函数声明(代码片段)

go函数特点函数是模块化、可复用、用于实现单一或相关联功能的代码块,用于执行一个任务。go函数具有以下特点:go工程至少有一个main()函数go语言通过函数来划分不同逻辑功能,每个函数执行指定任务go语言标准... 查看详情

5.go函数

【定义函数】直接上一个栗子,Go语言定义函数:funcadd(aint,bint)intreturna+b一目了然,还不太习惯Go语言的命名方式,类型为什么要写到后面?【多个返回值】Go函数还可以返回多个值:funcadd(aint,bint)(int,int)returna,a+b【命名返回值】f... 查看详情

go语言函数(代码片段)

函数Go语言和C语言一样也有函数的概念,Go语言中函数除了定义格式和不用声明以外,其它方面几乎和C语言一模一样格式:func函数名称(形参列表)(返回值列表)函数体;无参数无返回值函数funcsay() fmt.Println("HelloWorld!!!")有参数无... 查看详情

go函数参数

函数参数类型为:整数类型函数参数类型为:数组类型 查看详情

一文熟悉go函数

...狂热。哈喽大家好,我是陈明勇,今天分享的知识是Go的函数。如果本文对你有帮助,不妨点个赞,如果你是Go语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!函数函数的英文单词是​​Funct... 查看详情

go常用函数

1.字符串函数        查看详情

go语言|02for循环及常用函数的使用(代码片段)

文章目录前言for&range函数for语法for使用range遍历for循环嵌套breakmake&map函数make(集合)map(范围)delete()函数Go语言函数函数定义函数调用函数返回多个值Go语言函数值传递值Go语言函数引用传递值Go语言函数作... 查看详情

go语言|02for循环及常用函数的使用(代码片段)

文章目录前言for&range函数for语法for使用range遍历for循环嵌套breakmake&map函数make(集合)map(范围)delete()函数Go语言函数函数定义函数调用函数返回多个值Go语言函数值传递值Go语言函数引用传递值Go语言函数作... 查看详情

godefer(go延迟函数)

godefer(go延迟函数)Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此。根据GOLANGUAGESPEC的说法:A"defer"statementinvokesafunctionwhoseexecutionisdeferredtothemomentthesurroundingfunctionreturns,eitherbecausethesurroundingfunc 查看详情

go语言递归函数

Go语言递归函数递归,就是在运行的过程中调用自己。语法格式如下:1funcrecursion(){2recursion()/*函数调用自身*/3}45funcmain(){6recursion()7}Go语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。... 查看详情

go语言学习之旅--函数(代码片段)

函数GoLang函数介绍Go语言中函数特性函数的定义匿名函数闭包deferinit函数GoLang函数介绍函数的go语言中的一级公民,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称、参数列表和返回值类型... 查看详情

go-函数

定义语法-func函数名(参数列表)(返回值列表){}packagemainimport("fmt")funcmyfunc(a,bint)(r1,r2int){r1=a+br2=a-breturn}funcmain(){r1,r2:=myfunc(5,1)fmt.Println(r1)fmt.Println(r2)}//output64 匿名函数Go 语言允许将函数传递给一个变 查看详情

[golang]go中函数和方法的区分(代码片段)

说明在很多的语言当中,函数就是方法,例如Java。但是在go语言当中,函数和方法不太一样,有明确的概念区分。go中,函数是指不属于任何结构体、类型的方法,也就是说,函数是没有接收者的;而方法有接收者。我们在go中... 查看详情

go语言函数语法下篇(代码片段)

...录一、延迟执行语句defer1.1defer概念1.2使用演示二、递归函数三、Go语言处理运行时错误3.1错误处理思想3.2错误接口的定义四、Go语言宕机五、Go语言宕机恢复recover5.1基础概念5.2让程序在崩溃时继续执行5.3panic和recover的关系六、计... 查看详情

1.4go微服务实战(go语言基础)---函数方法接口和反射

第4章 函数、方法、接口和反射4.1 函数 4.1.1 函数的定义 4.1.2 闭包 Go语言中的闭包就是引用了自由变量的函数,被引用的自由变量同函数一直存在,即时离开了自由变量的环境也不会被释放和删除。闭包中可以 继... 查看详情