【Go语言】Go语言中的函数

news2025/1/11 16:55:58

Go语言中的函数

Go语言中,函数主要有三种类型:

  • 普通函数

  • 匿名函数(闭包)

  • 类方法

1 函数定义

Go语言函数的基本组成包括:关键字func、函数名、参数列表、返回值、函数体和返回语句。Go语言是强类型语言,无论是参数还是返回值,在定义函数时,都需要声明其类型。

如下是Go语言中函数的一个简单示例:

// 参数类型 int
// 返回类型 int
func add(a, b int) int  {
    return a + b
}

2 函数调用

2.1 调用同一个包定义的函数

如果函数在同一个包中,只需要直接调用即可:

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

func main()  {
    fmt.Println(add(1, 2))  // 3
}

2.2 调用其他包定义的函数

如果函数是在不同的包中,需要先导入该函数所在的包,然后才能调用该函数,例如 Add 函数在 calculator 包中。

package calculator

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

在 main 包中调用Add函数。

package main

import (
    "fmt"
    "calculator"
)
func main()  {
    fmt.Println(calculator.Add(1, 2))   // 3
}

注意:在调用其他包定义的函数时,只有这个函数名首字母大写的才可以被调用,例如函数名为add就会出现如下情况:

2.3 系统内置函数

Go语言中内置了常用的函数,如下所示

名称说明
close用于在管道通信中关闭一个管道
lencaplen 用于返回某个类型的长度(字符串、数组、切片、字典和管道),cap 则是容量的意思,用于返回某个类型的最大容量(只能用于数组、切片和管道)
newmakenewmake 均用于分配内存,new 用于值类型和用户自定义的类型(类),make 用于内置引用类型(切片、字典和管道)。它们在使用时将类型作为参数:new(type)make(type)new(T) 分配类型 T 的零值并返回其地址,也就是指向类型 T 的指针,可以用于基本类型:v := new(int)make(T) 返回类型 T 的初始化之后的值,所以 make 不仅分配内存地址还会初始化对应类型。
copyappend分别用于切片的复制和动态添加元素
panicrecover两者均用于错误处理机制
printprintln打印函数,在实际开发中建议使用 fmt 包
complexrealimag用于复数类型的创建和操作

3 参数传递

3.1 按值传参

Go语言默认使用按值传参来传递参数,也就是传递参数值的一个副本,函数收到传递进来的参数后,会将参数值拷贝给声明该参数的变量(也叫做形式参数,简称形参),如果在函数体中有对参数值做修改,实际上修改的是形参值,这不会影响到实际传递进来的参数值(也叫实际参数,简称实参)。

示例代码如下:

// a,b 是形式参数
func add(a, b int) int  {
    a *= 2
    b *= 3
    return a + b
}
func main()  {
    x, y := 1, 2
    // x,y 是实际参数
    z := add(x, y)
    // z的值是x*2+y*3=8,但x,y的值并未改变
    fmt.Printf("add(%d, %d) = %d\n", x, y, z)  
}

3.2 引用传参

如果需要实现在函数中修改形参值的同时改变实参,需要引用传参来实现,此时传递给函数的参数是一个指针,而指针代表的是实参的内存地址,修改指针引用的值即修改变量内存地址中存储的值,因此实参的值也会被修改。

示例代码如下:

// a,b 是形式参数
func add(a, b *int) int  {
    *a *= 2
    *b *= 3
    return *a + *b
}
func main()  {
    x, y := 1, 2
    // x,y 是实际参数
    z := add(&x, &y)
    // z的值是x*2+y*3=8,由于我们直接修改了内存超出地址的值,因此x变为2,y变为6
    fmt.Printf("add(%d, %d) = %d\n", x, y, z)  
}

在函数调用时,像切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型默认使用引用传参。

4 变长参数

变长参数指的是函数参数的数量不确定,可以按照需要传递任意数量的参数到函数。

4.1 基本定义和传值

只需要在参数类型前加上 ... 前缀,就可以将该参数声明为变长参数。

// 函数Myfunc()接受任意数量的参数,这些参数的类型全部是int
func Myfunc(numbers ...int){
    for _,number := range numbers {
        fmt.Println(number)
    }
}
// 函数可以按照如下方式调用:
Myfunc(1,2,3,4,5,6)
Myfunc(1,2,3)

函数调用测试:

变长参数还支持传递一个 []int 类型的切片,传递切片时需要在末尾加上 ... 作为标识,标识对应的参数类型是变长参数:

slice := []int{1,2,3,4,5,6}
Myfunc(slice...)
Myfunc(slice[1:3]...)

注:...type 只能作为函数的参数类型存在,并且必须是函数的最后一个参数。

4.2 任意类型的变长参数(泛型)

Go语言中,可以通过指定变长参数类型为 interface{} 来实现参数的任意类型传递。

代码实现如下:

// 变长参数,可以传递任意个数的参数,类型无要求
func Myfunc2(params ...interface{}) {
	for _, param := range params {
		fmt.Println(param)
	}
}

5 多返回值

5.1 多返回值

Go语言中,函数能够支持多返回值,经常用在程序出错的时候。

代码示例如下:

// 函数定义
func AddFunc(a, b *int) (int, error) {
	if *a < 0 || *b < 0 {
		err := errors.New("仅支持非负整数的相加")
		return 0, err
	}
	return *a + *b, nil
}
// 函数调用
x, y := -1, 2
z, err := function.AddFunc(&x, &y)
if err != nil {
    fmt.Println(err.Error())
    return
}
fmt.Printf("%d + %d = %d", x, y, z)

5.2命名返回值

函数设置多返回值时,还可以对返回值进行变量命名,这样就可以直接在函数中对返回值变量进行赋值,而不需要按照指定的返回值格式返回多个变量。

代码示例:

// 函数定义
func AddFunc2(a, b *int) (c int, err error) {
	if *a < 0 || *b < 0 {
		err = errors.New("仅支持非负整数的相加")
		return
	}
	c = *a + *b
	return
}
// 函数调用
x, y := -1, 2
z, err := function.AddFunc2(&x, &y)
if err != nil {
    fmt.Println(err.Error())
    return
}
fmt.Printf("%d + %d = %d", x, y, z)

6 匿名函数与闭包

6.1 匿名函数的定义和使用

匿名函数是一种没有指定函数名的函数声明方式。

代码示例如下:

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

Go语言中,匿名函数也可以赋值给一个变量或者直接执行:

// 将匿名函数赋值给变量
sum := func(a,b int) int {
    return a+b
}
// 调用匿名函数 add
fmt.Print(sum(1,2))

// 也可以在定义的时候,直接调用匿名函数
func(a,b int){
    fmt.Println(a+b)
} (1,2)

6.2 匿名函数与闭包

闭包:指引用了外部函数作用域中的变量的函数。也即,闭包是一个函数及其相关引用环境的组合。

匿名函数和闭包的关系:匿名函数可以用来创建闭包,当一个匿名函数引用了外部函数作用域中的变量时,该匿名函数就成了一个闭包。

6.3 匿名函数的使用场景

6.3.1 保证局部变量的安全性

匿名函数内部声明的局部变量无法从外部修改,从而确保了安全性(类似类的私有属性)。

代码示例如下:

var j int =1
f := func(){
    var i int = 1
    fmt.Println(i,j)
}
f()
j += 2
f()

如上代码运行所示,匿名函数引用了外部变量j,所以同时也是个闭包,变量f指向的闭包引用了局部变量i和j,i在闭包内定义,其值被隔离,不能从外部修改变量,j在闭包外定义,所以可以从外部修改,闭包只是引用了变量j的值。

6.3.2 将匿名函数作为函数参数

匿名函数除了可以赋值给普通变量外,还可以作为函数参数传递到函数中进行调用,就像普通数据类型一样。

代码示例:

add := func(a, b int) int {
    return a + b
}
func(call func(int, int) int) {
    fmt.Println(call(1, 2))
}(add)

6.3.3 将匿名函数作为函数返回值

Go语言中,匿名函数也能够作为返回值使用。

代码示例:

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

// 此时返回的是匿名函数
addFunc := defaultAdd(1, 2)
// 这里才会真正的执行加法操作
fmt.Println(addFunc())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1519956.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C#】数组string类型输出

示例 代码 internal class Program{static void Main(string[] args){List<int> list new List<int>() { 1,2,3,4,5,6,7,8,9,10};string output1 string.Join(",", list);Console.WriteLine(output1);string output2 string.Join("\n", lis…

深度学习指标| 置信区间、Dice、IOU、MIOU、Kappa

深度学习部分指标介绍 置信区间混淆矩阵DiceIOU和MIOUKappa 置信区间 95%CI指标 读论文的时候&#xff0c;常会看到一个“95%CI”的评价指标。 其中CI指的是统计学中的置信区间&#xff08;Confidence interval&#xff0c;CI&#xff09;。在统计学中&#xff0c;一个概率样…

【Streamlit学习笔记】实现包含多个sheet的excel文件下载

1、什么是Streamlit Streamlit是一个免费的开源框架&#xff0c;用于快速构建和共享漂亮的机器学习和数据科学Web应用程序&#xff0c;官网链接 Streamlit Streamlit API链接 API reference 实际项目中遇到的问题&#xff1a;包含多个sheet的excel文件下载&#xff0c;下面将给…

小程序路由跳转---事件通信通道EventChannel(二)

事件通信通道EventChannel实现两个页面之间的数据传输已在上篇小程序路由跳转—事件通信通道EventChannel&#xff08;一&#xff09;展开叙述&#xff0c;接下来讨论下多个页面&#xff08;三个及以上&#xff09;数据的通道如何构建。 本文重点&#xff1a;三个以上页面需将…

使用 Boot Camp 助理查明您的 Mac 需不需要 Windows 安装介质

使用 Boot Camp 助理查明您的 Mac 需不需要 Windows 安装介质 当前的 Mac 机型无需介质即可安装 Windows&#xff0c;也就是说&#xff0c;您不需要用到外置驱动器。较早的 Mac 机型需要用到 USB 驱动器或光盘驱动器。使用 Boot Camp 助理可查明您需要用到什么。 Boot Camp 助…

openGauss使用BenchmarkSQL进行性能测试(下)

上一篇我们分享了测试方法&#xff0c;本篇我们将发起测试及测试结果。 背景 本文提供openGauss使用BenchmarkSQL进行性能测试的方法和测试数据报告。 BenchmarkSQL&#xff0c;一个JDBC基准测试工具&#xff0c;内嵌了TPC-C测试脚本&#xff0c;支持很多数据库&#xff0c;…

百度paddleocr GPU版部署

显卡&#xff1a;NVIDIA GeForce RTX 4070&#xff0c;Nvidia驱动程序版本&#xff1a;537.13 Nvidia驱动程序能支持的最高cuda版本&#xff1a;12.2.138 Python&#xff1a;python3.10.11。试过python3.12&#xff0c;安装paddleocr失败&#xff0c;找不到相关模块。 飞桨版本…

使用C#的winform控制数据库实例服务的运行状态

一、得到sqlserver的实例名 二、引用对应的程序集和命名空间 using System.ServiceProcess; C#操作服务要用的类 ServiceController 声明类 private ServiceController serviceController new ServiceController("MSSQLSERVER"); 三、判断服务状态 serviceCon…

centos云服务器安装cs(cobaltstrike4.0)教程

1、先安装JAVA环境 mkdir download #创建download目录 cd download #进入download目录 mkdir java1.8 #在download目录下再创建java1.8目录 cd java1.8 #进入java1.8目录 wget https://repo.huaweicloud.com/java/jdk/8u201-b09/jdk-8u201-linux-x64.tar.gz #下载jdk压缩包 tar…

HarmonyOS NEXT应用开发—验证码布局

介绍 本示例介绍如何使用Text组件实现验证码场景&#xff0c;并禁用对内容的选中、复制、光标。 效果图预览 使用说明 单击组件可弹出输入法在进行验证码输入时&#xff0c;无法对中间单个数字进行更改&#xff0c;无法选中输入内容&#xff0c;无光标 实现思路 因为要禁用…

c语言实现https客户端 源码+详细注释(OpenSSL下载,visual studio编译器环境配置)

OpenSSL的下载和环境配置 请参考&#xff1a;openssl下载安装教程 步骤&#xff1a;官网下载->安装到选定目录->配置环境变量->打开命令窗口检查是否安装成功 注意&#xff1a; 打开命令窗口&#xff08;快捷键winr,在弹出窗口内输入cmd按回车&#xff09;&#xff0…

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+OSD动态字符叠加,提供1套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收HLS多路视频融合叠加应用本方案的S…

用连续自然数之和来表达整数 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 一个整数可以由连续的自然数之和来表示。给定一个整数&#xff0c;计算该整数有几种连续自然数之和的表达式&#xff0c;且打印出每种表达式。 输入描述 一个目…

1.Python数据分析—数据分析与挖掘详讲

1.Python数据分析—数据分析与挖掘详讲 一个人简介二数据分析与挖掘概述三什么是数据分析和挖掘四数据分析与挖掘在不同领域的应用4.1医疗领域&#xff1a;4.1.1 建立疾病数据库&#xff1a;4.1.2 临床决策支持&#xff1a;4.1.3 疾病预警和监控&#xff1a; 4.2 电子商务领域&…

还原wps纯粹的编辑功能

1.关闭稻壳模板&#xff1a; 1.1. 启动wps(注意不要乱击稻壳模板&#xff0c;点了就找不到右键菜单了) 1.2. 在稻壳模板选项卡右击&#xff1a;选不再默认展示 2.关闭托盘中wps云盘图标&#xff1a;右击云盘图标/同步与设置&#xff1a; 2.1.关闭云文档同步 2.2.窗口选桌面应用…

【Unity+Vuforia】AR 发布安卓的设置

Player Settings > Resolution and Presentation > Default Orientation portrait Player Settings > Other Settings > Auto Graphics API 取消勾选 Player Settings > Other Settings > Graphics APIs 选择OpenGLES3删除其他的 Player Settings…

【矩阵】54. 螺旋矩阵【中等】

螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 解题思路 1、模拟顺时针螺旋顺序遍历矩阵…

pytorch之诗词生成6--eval

先上代码&#xff1a; import tensorflow as tf from dataset import tokenizer import settings import utils# 加载训练好的模型 model tf.keras.models.load_model(r"E:\best_model.h5") # 随机生成一首诗 print(utils.generate_random_poetry(tokenizer, model)…

Vscode中关于Java的一些问题

前言 在使用Vscode的时候&#xff0c;总是会有这么一种感觉&#xff1a;有时得这样&#xff0c;有时得那样&#xff0c;这让我甚是困惑&#xff0c;于是写下来这篇解答文章 为什么java文件有时候会有class文件&#xff0c;有时候没有 在编写Java代码时&#xff0c;我会有一种…

自习室预订系统|基于springboot框架+ Mysql+Java+B/S架构的自习室预订系统设计与实现(可运行源码+数据库+设计文档+部署说明)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 学生功能模块 管理员功能登录前台功能效果图 系统功能设计 数据库E-R图设计 lunwen参…