【第十八篇】一文搞懂_GO语言_函数注意事项和细节🔥🔥

115 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

一、函数注意事项和细节讨论:

  1. 函数的形参列表可以是多个,返回值列表也可以是多个。
  2. 形参列表和返回值列表的数据类型可以是值类型和引用类型。
  3. 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其它包文件使用,类似public,首字母小写,只能被本包文件使用,其它包文件不能使用,类型 private
  4. 函数中的变量是局部的,函数外不生效。
package main

import "fmt"

func test() {

	// n1 是 test 函数的局部变量,只能在test函数中使用
	var n1 int = 10

}
func main() {
	// 这里不能使用n1 ,因为 n1 是test 函数的局部变量
	fmt.Println("n1="n1)

}


  1. 基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。

值传递:拷贝了一份数据,不影响原来的数值,被拷贝的可以是值也可以是地址

引用传递:通过指针直接修改的源数值

package main

import "fmt"

func test02(n1 int) {

	n1 = n1 + 10
	fmt.Println("test01() n1=", n1)
}
func main() {
	// 这里不能使用n1 ,因为 n1 是test 函数的局部变量
	n1 := 20
	test02(n1)
	fmt.Println("main() n1=", n1)

}

main() 函数下 test02(n1) 进行了一个值拷贝 , 传递给 test02 函数


  1. 如果希望函数内的变量能修改函数外的变量(指的是默认以值传递的方式的数据类型),可以传入变量的地址 & ,函数内以指针的方式操作变量。从效果上看类似引用

值传递:传递的是原本的数值

引用传递:传递地址值

*:取值

&:取地址

package main

import "fmt"

// n1 就是 *int 类型
func test03(n1 *int) {

	*n1 = *n1 + 10
	fmt.Println("test03() n1=", *n1)
}
func main() {

	num := 20
	test03(&num)
	fmt.Println("main() num=", num)
}


  1. Go 函数不支持重载
  2. 在 GO 中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用。
package main

import "fmt"

// 在 GO 中,函数也是一种数据类型,
// 可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用。

func getSum(n1 int, n2 int) int {
	return n1 + n2
}
func main() {

	a := getSum
	fmt.Printf("a的类型%T\ngetSum类型是%T\n", a, getSum)

	res := a(10, 40) // 等价于 res := getSum(10,40)
	fmt.Println("res=", res)
}


  1. 函数既然是一种数据类型,因此在GO中,函数可以作为形参,并且调用!
package main

import "fmt"

// 在 GO 中,函数也是一种数据类型,
// 可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用。

func getSum(n1 int, n2 int) int {
	return n1 + n2
}

// 函数既然是一种数据类型,因此在GO中,函数可以作为形参,并且调用!
func myFun(funvar func(int, int) int, num1 int, num2 int) int {
	return funvar(num1, num2)
}
func main() {

	a := getSum
	fmt.Printf("a的类型%T\ngetSum类型是%T\n", a, getSum)

	res := a(10, 40) // 等价于 res := getSum(10,40)
	fmt.Println("res=", res)

	// 看案例:
	res2 := myFun(getSum, 50, 60)
	fmt.Println("res2=", res2)
}


  1. 为了简化数据类型定义,GO支持自定义数据类型
    1. 基本语法:type 自定义数据类型名 数据类型 // 理解:相当于一个别名
    2. 案例:type mylnt int // 这时 myint 就等于 int 来使用了
    3. 案例:type mySum func (int ,int)int //这时 mySum 就等价于一个函数类型 func (int,int) int
package main

import "fmt"

// 在 GO 中,函数也是一种数据类型,
// 可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用。

func getSum(n1 int, n2 int) int {
	return n1 + n2
}

// 函数既然是一种数据类型,因此在GO中,函数可以作为形参,并且调用!
// func myFun(funvar func(int, int) int, num1 int, num2 int) int {
// 	return funvar(num1, num2)
// }

// 再举一个案例:
// 案例 二
// 这时 myFunType 就是 func(int,int)int
type myFunType func(int, int) int // 这时 myFunType

func myFun2(funvar myFunType, num1 int, num2 int) int {
	return funvar(num1, num2)
}

func main() {

	// 案例 一:
	// 给 int 取了别名,在go中 myInt 和 int ,虽然都是数据类型,但是go认为 myInt 和 int 是两个类型
	type myInt int
	var num1 myInt
	var num2 int
	num1 = 40
	num2 = int(num1) // 各位,注意这样依然需要显示转换,go 认为myInt和int两个类型
	fmt.Println("num1=", num1, "num2", num2)

	res3 := myFun2(getSum, 50, 60)
	fmt.Println("res3=", res3)
}


  1. 支持对函数返回值的命名
package main

import "fmt"

// 支持对函数返回值命名:
func getSumAndSub(n1 int, n2 int) (sum int, sub int) {
	sum = n1 + n2
	sub = n1 - n2
	return

}
func main() {

	// 看案例:
	a, b := getSumAndSub(1, 2)
	fmt.Printf("a=%v b=%v\n", a, b)

}