[GO programming language] function

function



insert image description here


1. What is a function

  • Functions are basic blocks of code that perform a task.
  • Go language has at least one main( ) function.
  • Functions can be used to divide different functions, and logically each function performs a specified task.
  • A function declaration tells the compiler the function's name, return type, and parameters.

1. Function declaration

The format of Go language function definition is as follows:

func functionName( [parameter list] ) [returnType] {
    
    
		函数体
}
package main

import "fmt"

/*
	-- 函数是基本的代码块,用于执行一个任务
	-- Go 语言最少有个 main() 函数
	-- 可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务
	-- 函数声明告诉了编译器函数的名称,返回类型和参数
*/

func main() {
    
    

	fmt.Println(add(3, 4))

}

// func 函数名 (参数,参数....) 函数调用后的返回值 {
    
    
//  函数体 : 执行一段代码
//  return  返回结果
//}

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

output
insert image description here

2. Function declaration and call

  • function with no parameters and no return value
  • function with one parameter
  • function with two parameters
  • has a function that returns the value
  • Functions with multiple return values
package main

import "fmt"

func main() {
    
    

	c := add(3, 4)
	fmt.Println(c)
	onePrint("guan")
	x, y := swap("guan", "hello")
	fmt.Println(x, y)
}

// - 无参数无返回值函数
func Println() {
    
    
	fmt.Println("printinfo")
}

// - 有一个参数的函数
func onePrint(name string) {
    
    
	fmt.Println("name")
}

// - 有两个参数的函数
// - 有一个返回值的函数
func add(a, b int) int {
    
    
	c := a + b
	return c
}

// - 有多个返回值的函数
func swap(x, y string) (string, string) {
    
    
	return y, x
}

output
insert image description here

3. Formal parameters and actual parameters

Formal parameter: When defining a function, the parameter used to receive incoming data from other ports is the formal parameter

Actual parameter: When calling a function, the actual data passed to the formal parameter is called the actual parameter

package main

func main() {
    
    
	maxNum := max(6, 8)
	println(maxNum)

}

// - max 两个数字比大小
// 形式参数:定义函数时,用来接收外埠传入数据的参数,就是形式参数
// 实际参数:调用函数时,传给形参的实际数据叫做实际参数
func max(num1, num2 int) int {
    
    
	var result int
	if num1 > num2 {
    
    
		result = num1
	} else {
    
    
		result = num2
	}
	// 一个函数定义上有返回值,那么函数中必须使用return语句
	// 返回值
	// 调用处需要使用变量接收结果
	return result
}

Four, variable parameters

Concept: If the parameter type of a function is determined, but the number is uncertain, variable parameters can be used.

func myfunc(arg ... int) {
    
    }
// arg ... int 告诉go这个函数接收不定数量的参数,类型全部是int
package main

import "fmt"

func main() {
    
    
	getSum(1, 2, 3, 4, 5, 6, 7, 8)
}

// ... 可变参数
func getSum(nums ...int) {
    
    
	sum := 0
	// x.len(),获取元素长度
	for i := 0; i < len(nums); i++ {
    
    
		// x[i] 通过下标取出数据
		sum += nums[i]
	}
	fmt.Println("总和:", sum)
}

output
insert image description here

5. Passing by value and passing by reference

According to the characteristics of data storage:

  • Data of value type: the operation is data body, int, string, bool, float64, array...
  • Yinchuan type of data: the operation is the address of the data slice, map, chan...

pass by value

package main

import "fmt"

func main() {
    
    
	// 定义一个数组
	arr1 := [4]int{
    
    1, 2, 3, 4}
	fmt.Println("arr1默认数据", arr1)
	update(arr1)
	fmt.Println("arr1 调用函数后数据", arr1)

	// arr2 的数据是 从arri 复制兴的,所以是不可的空间
	// 修改 arr2 并不会影响 arr 1
	// 值传递:传递的是数据的副本,修改数据,对于原始约数据没有影响
	// 值类型的数据,默认都是值传递:基础炎型、array、struct
}

func update(arr2 [4]int) {
    
    
	fmt.Println("arr2 接以数据", arr2)
	arr2[0] = 10
	fmt.Println("arr2 修改后数据", arr2)
}

Output
insert image description here
Notes:

  • If a function parameter is a variable parameter, and there are other parameters, the variable parameter should be placed at the end of the list.
  • A function can have at most one variable parameter in its parameter list.

6. The scope of variables in functions

  • Scope: the scope in which the variable can be used
  • Local variables: Variables defined inside a function are called local variables
package main

import "fmt"

func main() {
    
    
	// 函数体内的局部变量
	y := 66
	if z := 1; z <= 10 {
    
    
		// 语句内的局部变量
		y := 88
		fmt.Println(y) // 局部变量,就近原则
		fmt.Println(z)
	}
	fmt.Println(y)
	//fmt.Println(z) // # command-line-arguments
	// .\hello.go:15:14: undefined: z
}

func gun01() {
    
    
	// x 为局部变量
	x := 1
	println(x)
}

func gun02() {
    
    
	// fmt.Println(a) //不能在使用在其他函数定义的变量
}

  • All variables: Variables defined outside the function are called global variables
package main

import "fmt"

// 全局变量
var num int = 99

func main() {
    
    
	//num := 1
	fmt.Println(num)
	gun01()
	gun02()
}

func gun01() {
    
    
	//num := 2
	println(num)
}

func gun02() {
    
    
	//num := 3
	fmt.Println(num)
}

output
insert image description here

insert image description here

Seven, defer

defer Semantics: defer, delay

In Go language, use the defer keyword to delay the execution of a function or method.

package main

import "fmt"

func main() {
    
    
	num := 1
	fmt.Println(num)
	defer gun01() // 会被延迟到最后执行
	gun02()
}

func gun01() {
    
    
	num := 2
	println(num)
}

func gun02() {
    
    
	num := 3
	fmt.Println(num)
}

output
insert image description here

defer function or method: the execution of a function or method is delayed

  • You can add multiple defer statements in the function, 当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回especially when you are performing some resource opening operations and you need to return in advance if you encounter an error, you need to close the corresponding resource before returning, otherwise it is easy to cause resource leakage and other problems
  • If there are many calls to defer, then defer adopts the last-talk-first-out (stack) mode.
package main

import "fmt"

func main() {
    
    
	num := 1
	num01 := 6
	fmt.Println(num)
	defer gun01() // 会被延迟到最后执行
	defer gun02()
	defer fmt.Println(num01)
}

func gun01() {
    
    
	num := 2
	println(num)
}

func gun02() {
    
    
	num := 3
	fmt.Println(num)
}

output
insert image description here

import "fmt"

func main() {
    
    
	num := 1
	a := 6
	fmt.Println(num)
	defer gun01(a) // 在执行a++之前,参数就已经传递进去了,在最后执行
	a++
	fmt.Println(a)

}

func gun01(x int) {
    
    

	println(x)
}

output
insert image description here

8. Inquiry into the nature of functions

package main

import "fmt"

// func() 本身就是一个数据类型
func main() {
    
    
	// f1 如果不加括号,函数也是一个变量
	// f1() 如果加了括号,那就成了函数的调用
	fmt.Print("%T\n", f1)

	// f1 看着对应函数名对应函数体的地址 0xbbfd60
	// f1() 带括号就是将函数直接调用

	// 直接定义一个函数类型的变量
	fmt.Println()
	var x func(int, int)
	fmt.Println(x)

	// 将格式相同的f1给x进行函数赋值
	x = f1
	fmt.Println(x) // 和f1地址相同

	f1(1, 2)
	x(10, 20) //x也是函数类型的,可以直接调用
}

func f1(a, b int) {
    
    
	fmt.Printf("a:%d,b:%d\n", a, b)
}

insert image description here
函数在 Go 语言中是复合类型,可以看做是一种特殊的变量。
Function name ( ): the return result of the call
Function name: the memory address pointing to the function body, a special type of pointer variable

9. Anonymous functions

package main

import "fmt"

// func() 本身就是一个数据类型
func main() {
    
    
	f1()
	f2 := f1 //函数本身也是一个变量
	f2()

	// 匿名函数
	f3 := func() {
    
    
		fmt.Println("f3函数")
	}
	f3()

	func() {
    
    
		fmt.Println("f4函数")
	}() // 匿名函数本身可以调用自己

	func(a, b int) {
    
    
		fmt.Println(a, b)
		fmt.Println("f5函数")
	}(3, 4) // 匿名函数本身可以调用自己

	x := func(a, b int) int {
    
    
		fmt.Println("f6函数")
		return a + b

	}(3, 4) // 匿名函数本身可以调用自己
	fmt.Println(x)
}

func f1() {
    
    
	fmt.Println("f1函数")
}

Go language supports functional programming:
1. Use an anonymous function as a parameter of another function, and call back a function
2. Use an anonymous function as the return value of another function to form a closure structure

10. Callback function

According to the characteristics of data types in Go language, 可以将一个函数作为另外一个函数的参数.
fun1(), fun2() use the fun1 function as the parameter of the fun2 function

fun2 function: called a higher-order function, a function that receives a function as a parameter

fun1 function: called callback function, as a parameter of another function

package main

import "fmt"

func main() {
    
    
	r1 := Sum(1, 1)
	fmt.Println(r1)

	r2 := oper(5, 5, Sum)
	fmt.Println(r2)

	r3 := oper(10, 5, Sub)
	fmt.Println(r3)

	r4 := oper(10, 5, func(a int, b int) int {
    
    
		if b == 0 {
    
    
			fmt.Println("除数不能为0")
			return 0
		}
		return a / b
	})
	fmt.Println(r4)
}

// 高阶函数,可以接收一个函数作为参数
func oper(a, b int, f func(int, int) int) int {
    
    
	r := f(a, b)
	return r

}

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

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

output
insert image description here

Eleven, closure

  • In an outer function, there is a human layer function. In this human layer function, the local variables of the outer layer function will be operated. The outer layer function will return and pass to this human layer function. The spiritual part variables of the inner feather number and the outer urine number are collectively called the closure structure

  • The life cycle of local variables will change. Normal local variables will be created with the adjustment of the function, and will be destroyed with the end of the function. As a closed structure, the local variables with the number of external columns will not be destroyed with the calculation of the outer function, because the internal function certificate will continue to be used.



package main

import "fmt"

func main() {
    
    
	r1 := increment()
	fmt.Println(r1)

	v1 := r1()
	fmt.Println(v1)

	v2 := r1()
	fmt.Println(v2)
	fmt.Println(r1())
	fmt.Println(r1())
	fmt.Println(r1())

	r2 := increment()
	v3 := r2()
	fmt.Println(v3)
	fmt.Println(r1())
	fmt.Println(r2())
}

func increment() func() int {
    
    
	// 局部变量i
	i := 0
	// 定义一个匿名函数,给变量自增并返回
	f := func() int {
    
    
		i++
		return i
	}
	return f
}




Guess you like

Origin blog.csdn.net/guanguan12319/article/details/130587071