Go中函数的使用细节与注意事项详解

 更新时间:2022年11月26日 16:09:07   作者:甜点cc  
在Go语言中函数可是一等的(first-class)公民,函数类型也是一等的数据类型,下面这篇文章主要给大家介绍了关于Go中函数的使用细节与注意事项的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

细节汇总

  • 函数的形参列表可以是多个,返回值列表也可以是多个
  • 形参列表和返回值列表的数据类型,可以是值类型、也可以是引用类型
  • 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写表示该函数可以被本包文件和其它文件使用,类似public;首字母小写只能被本包文件使用,类似private。
  • 函数中的变量是局部的,外部不能访问。作用域
  • 基本数据类型和数组都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值,
  • 如果希望函数内的变量能够修改函数外的变量,可以传入变量的地址(&),函数内以指针的方式操作变量,从效果上看类似引用
  • Go函数不支持函数重载。
  • 在Go中,函数也是一种数据类型,可以赋值给一个变量,则该变量是一个函数类型的变量,通过该变量可以对函数调用。
  • 函数既然是一种数据类型,因此在Go中,函数也可以作为形参,并且调用。(回调函数
  • 为了简化数据类型定义,Go支持自定义数据类型
  • 语法: type 自定数据类型名 数据类型 (相当于一个别名)

  • 案例: type myInt int 这时,myInt就等价于int来使用了

  • type mySum func(int, int) int 这时,mySum就等价于func(int, int) int

  • 支持对函数返回值命名(可以不受返回值顺序限制
  • 使用 _ 下划线标识符,忽略返回值。(占位符
  • Go支持可变参数

值传递和指针传递

func test(n1 int) {
	n1 = n1 + 10
	fmt.Println("test n1=", n1)
}

// 指针类型接收处理
func test02(n2 *int) {
	*n2 = *n2 + 10
	fmt.Println("test02 n2=", *n2)
}

func main() {
	n1 := 20
	n2 := 2
	test(n1) // 值类型
	test02(&n2) // 指针类型
	fmt.Println("main n1=", n1)
	fmt.Println("main n2=", n2)
}

什么是重载

重载: 函数名相同,但是形参不同或者数据类型不同的情况。

Golang语言中是不支持传统的函数重载的,fn redeclared in this block

Golang语言是支持可变参数的,空接口的形式

函数类型的变量

类型: func(int, int) int

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

// main 函数
sumFn := getSum
res := sumFn(10, 20)
fmt.Printf("%T %v\n", res, res) // int 30
fmt.Printf("%T \n", sumFn) // func(int, int) int

sumsFn := getSums
result := sumsFn(10, 20, 30)
fmt.Printf("result : %T %v\n", result, result) // result : int 60
fmt.Printf("sumsFn类型:%T \n", sumFn) // sumsFn类型:func(int, int) int

函数作为形参传入

func getSum(n1 int, n2 int) int {
	return n1 + n2
}
func testFn(fnVar func(int, int) int, num1 int, num2 int) int {
	return fnVar(num1, num2) // 调用传入的函数,并返回值
}

// 函数类型形参
sumFn := getSum
total := testFn(sumFn, 1, 2)
fmt.Println("total=", total) // 3

自定义数据类型

  • 自定义函数数据类型, 相当于起了一个别名
type mySum func(int, int) int

func testFn(fnVar mySum, num1 int, num2 int) int {
	return fnVar(num1, num2)
}

// func testFn(fnVar func(int, int) int, num1 int, num2 int) int {
// 	return fnVar(num1, num2)
// }
  • 自定义数据类型
// main函数下
type myInt int
var num1 myInt = 2
// var num2 int = num1 // 这样是报错的, myInt和int并不等价
var num2 int = int(num1) // 显式类型转换
fmt.Printf("num1的类型:%T 值:%v \n", num1, num1) // num1的类型:main.myInt 值:2
fmt.Printf("num2的类型:%T 值:%v \n", num2, num2) // num2的类型:int 值:2
  • 定义的类型: 包名.类型名,如:utils.myInt
// 以下是utils包
package utils

import "fmt"

func TestFn() string {
	fmt.Println("TestFn 函数被调用")
	type myInt int
	var n myInt = 10
	fmt.Printf("n的类型:%T 值:%v", n, n) // n的类型:utils.myInt 值:10
	return "hahaha"
}

返回值命名

func sumSub(n1 int, n2 int) (sum int, sub int) {
    // 这里不需要声明sum, sub变量了,也不用在return时写
	sum = n1 + n2
	sub = n1 - n2
	return
}

// main函数
sum, sub := sumSub(9, 8)
fmt.Println("sum=", sum, "sub=", sub) // sum= 17 sub= 1

可变参数

基本语法

  • 支持零到多个参数

func sum(args... int) {}

  • 支持1到多个参数

func sum(n1 int, args... int) {}

args:就是一个承接的变量名,可以自定义,如:func sum(n1 int, **vars**... int) {}

说明:

  • args是slice切片,通过args[index]可以访问到各个值
  • args必须放到形参列表的最后面

参数个数可变

func sumV2(n1 int, args ...int) int {
	sum := n1
	fmt.Printf("args类型是:%T\n", args) // args类型是:[]int
	// 遍历args切片
	for i := 0; i < len(args); i++ {
		sum += args[i]
	}
	return sum
}

// main函数
// 参数可变
total02 := sumV2(1, 2, 3, 4)
fmt.Println("total02=", total02) // total02= 10

总结练习

交换变量a, b的值

package main

import "fmt"

func swap(n1 *int, n2 *int) {
	*n1 = *n1 + *n2
	*n2 = *n1 - *n2 // *n1
	*n1 = *n1 - *n2 // *n2
}

func main() {
	a := 12
	b := 20
	swap(&a, &b)
	fmt.Println("a = ", a, "b = ", b)
}

到此这篇关于Go中函数的使用细节与注意事项的文章就介绍到这了,更多相关Go函数使用和注意内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go切片的copy和view的使用方法

    go切片的copy和view的使用方法

    这篇文章主要介绍了go切片的copy和view的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 详解Go语言中切片的长度与容量的区别

    详解Go语言中切片的长度与容量的区别

    切片可以看成是数组的引用,切片的长度是它所包含的元素个数。切片的容量是从它的第一个元素到其底层数组元素末尾的个数。本文将通过示例详细讲讲Go语言中切片的长度与容量的区别,需要的可以参考一下
    2022-11-11
  • 分析Go错误处理优化go recover机制缺陷

    分析Go错误处理优化go recover机制缺陷

    这篇文章主要为大家介绍了分析Go错误处理优化go recover机制缺陷示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Go之集合slice的实现

    Go之集合slice的实现

    本文主要介绍了Go之集合slice的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • GO语言包管理工具go mod以及包详解

    GO语言包管理工具go mod以及包详解

    go mod是go的一个模块管理工具,用来代替传统的GOPATH方案,下面这篇文章主要给大家介绍了关于GO语言包管理工具go mod以及包详解的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • golang1.21新特性全面讲解

    golang1.21新特性全面讲解

    经过了半年左右的开发,golang 1.21 最近正式发布了,这个版本中有不少重要的新特性和变更,尤其是在泛型相关的代码上,下面小编就来和大家好好唠唠吧
    2023-08-08
  • Golang实现Java虚拟机之解析class文件详解

    Golang实现Java虚拟机之解析class文件详解

    这篇文章主要为大家详细介绍了Golang实现Java虚拟机之解析class文件的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • Golang中字符串(string)与字节数组([]byte)一行代码互转实例

    Golang中字符串(string)与字节数组([]byte)一行代码互转实例

    golang语言本身就是c的工具集,开发c的程序用到的大部分结构体,内存管理,携程等,golang基本都有,下面这篇文章主要给大家介绍了关于Golang中字符串(string)与字节数组([]byte)一行代码互转的相关资料,需要的朋友可以参考下
    2022-09-09
  • 详解Golang中gomock的使用场景和方法

    详解Golang中gomock的使用场景和方法

    gomock是Go编程语言的模拟框架, 它与Go的内置测试包很好地集成在一起,但也可以在其他上下文中使用,本文主要介绍了gomock的使用场景和方法,感兴趣的可以了解下
    2024-10-10
  • Go语言中的函数详解

    Go语言中的函数详解

    函数是基本的代码块,用于执行一个任务。本文详细讲解了Go语言中的函数,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论