跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) angular(82) LLM(75) 大语言模型(63) 人工智能(53) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(33) Go基础(29) Python(24) Vue(22) Web开发(20) Web技术(19) 精选资源(19) 深度学习(19) Java(18) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) 安卓(11) 聊天机器人(10) typescript(10) 资料精选(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) LLMOps(9) Go语言中级开发(9) 自然语言处理(9) PostgreSQL(9) 区块链(9) mlops(9) 安全(9) 全栈开发(8) ChatGPT(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) 数据科学(7) whisper(6) Prisma(6) 隐私保护(6) RAG(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 提示工程(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) 推荐系统(5) WebAssembly(5) GameDev(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) 智能体(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) 编程语言(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) kafka(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) nextjs(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) 大型语言模型(2) 语言模型(2) 可穿戴设备(2) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) 数据分析(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

介绍


函数是一段代码,一旦定义,就可以重用。函数用于通过将代码分解为可在整个程序中多次使用的小型、可理解的任务来使您的代码更易于理解。

Go 附带了一个强大的标准库,其中包含许多预定义的函数。您可能已经从 fmt 包中熟悉的是:

  • fmt.Println() 会将对象打印到标准输出(很可能是您的终端)。
  • fmt.Printf() 这将允许您格式化打印输出。

函数名称包括括号,并且可能包括参数。

在本教程中,我们将介绍如何定义您自己的函数以在您的编码项目中使用。

定义函数


让我们从经典的“Hello, World!”开始。程序化成一个函数。

我们将在我们选择的文本编辑器中创建一个新的文本文件,并调用程序 hello.go。然后,我们将定义函数。

函数是使用 func 关键字定义的。然后是您选择的名称和一组括号,其中包含函数将采用的任何参数(它们可以为空)。函数代码行用大括号 {} 括起来。

在这种情况下,我们将定义一个名为 hello() 的函数:

hello.go


func hello() {}


这设置了用于创建函数的初始语句。

从这里开始,我们将添加第二行来提供函数功能的说明。在这种情况下,我们将打印 Hello, World!到控制台:

hello.go


func hello() {
    fmt.Println("Hello, World!")
}


我们的函数现在已经完全定义好了,但是如果我们此时运行程序,什么都不会发生,因为我们没有调用该函数。

因此,在我们的 main() 函数块中,让我们用 hello() 调用该函数:

hello.go

package main

import "fmt"

func main() {
    hello()
}

func hello() {
    fmt.Println("Hello, World!")
}

现在,让我们运行程序:

go run hello.go


您将收到以下输出:

Output

Hello, World!


请注意,我们还引入了一个名为 main() 的函数。 main() 函数是一个特殊函数,它告诉编译器程序应该从这里开始。 对于您希望可执行的任何程序(可以从命令行运行的程序),您将需要一个 main() 函数。 main() 函数必须只出现一次,在 main() 包中,并且不接收和返回任何参数。 这允许在任何 Go 程序中执行程序。 根据以下示例:

main.go

package main

import "fmt"

func main() {
    fmt.Println("this is the main section of the program")
}

函数可以比我们定义的 hello() 函数更复杂。 我们可以在函数块中使用 for 循环、条件语句等。

例如,以下函数使用条件语句检查 name 变量的输入是否包含元音,然后使用 for 循环遍历 name 字符串中的字母。

names.go

package main

import (
    "fmt"
    "strings"
)

func main() {
    names()
}

func names() {
    fmt.Println("Enter your name:")

    var name string
    fmt.Scanln(&name)
    // Check whether name has a vowel
    for _, v := range strings.ToLower(name) {
        if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' {
            fmt.Println("Your name contains a vowel.")
            return
        }
    }
    fmt.Println("Your name does not contain a vowel.")
}

我们在这里定义的 names() 函数设置了一个带有输入的名称变量,然后在 for 循环中设置了一个条件语句。这显示了如何在函数定义中组织代码。但是,根据我们对程序的意图以及我们希望如何设置代码,我们可能希望将条件语句和 for 循环定义为两个独立的函数。

在程序中定义函数使我们的代码模块化和可重用,这样我们就可以调用相同的函数而无需重写它们。

使用参数


到目前为止,我们已经研究了带有空括号且不带参数的函数,但是我们可以在函数定义中的括号内定义参数。

参数是函数定义中的命名实体,指定函数可以接受的参数。在 Go 中,您必须为每个参数指定数据类型。

让我们创建一个将单词重复指定次数的程序。它将采用一个名为 word 的字符串参数和一个名为 reps 的 int 参数来表示重复单词的次数。

repeat.go

package main

import "fmt"

func main() {
    repeat("Sammy", 5)
}

func repeat(word string, reps int) {
    for i := 0; i < reps; i++ {
        fmt.Print(word)
    }
}

我们为 word 参数传递了值 Sammy,为 reps 参数传递了 5。 这些值按照给定的顺序与每个参数相对应。 repeat 函数有一个 for 循环,它将迭代 reps 参数指定的次数。 对于每次迭代,都会打印 word 参数的值。

这是程序的输出:

Output
SammySammySammySammySammy


如果你有一组参数都是相同的值,你可以省略每次指定类型。 让我们创建一个小程序,接收参数 x、y 和 z,它们都是 int 值。 我们将创建一个函数,在不同的配置中将参数添加在一起。 这些总和将由函数打印。 然后我们将调用该函数并将数字传递给该函数。

add_numbers.go

package main

import "fmt"

func main() {
    addNumbers(1, 2, 3)
}

func addNumbers(x, y, z int) {
    a := x + y
    b := x + z
    c := y + z
    fmt.Println(a, b, c)
}

当我们为 addNumbers 创建函数签名时,我们不需要每次都指定类型,而只在最后指定。

我们为 x 参数传递了数字 1,为 y 参数传递了 2 in,为 z 参数传递了 3 in。这些值按照给定的顺序与每个参数对应。

该程序正在根据我们传递给参数的值进行以下数学运算:

  • a = 1 + 2
  • b = 1 + 3
  • c = 2 + 3

该函数还打印 a、b 和 c,根据这个数学,我们期望 a 等于 3,b 等于 4,c 等于 5。让我们运行程序:

go run add_numbers.go

Output
3 4 5


当我们将 1、2 和 3 作为参数传递给 addNumbers() 函数时,我们会收到预期的输出。

参数是通常在函数定义中定义为变量的参数。当您运行方法时,可以为它们赋值,将参数传递给函数。

返回值


可以将参数值传递给函数,函数也可以产生值。

函数可以使用 return 语句生成一个值,该语句将退出函数并可选地将表达式传递回调用者。还必须指定返回数据类型。

到目前为止,我们在函数中使用了 fmt.Println() 语句而不是 return 语句。让我们创建一个程序,而不是打印将返回一个变量。

在一个名为 double.go 的新文本文件中,我们将创建一个将参数 x 加倍并返回变量 y 的程序。我们发出调用以打印结果变量,该变量是通过运行带有 3 的 double() 函数形成的:

double.go

package main

import "fmt"

func main() {
    result := double(3)
    fmt.Println(result)
}

func double(x int) int {
    y := x * 2
    return y
}

我们可以运行程序并查看输出:

go run double.go



Output

6


整数 6 作为输出返回,这是我们将 3 乘以 2 所期望的结果。

如果函数指定了返回值,则必须在代码中提供返回值。 如果不这样做,您将收到编译错误。

我们可以通过用 return 语句注释掉这一行来证明这一点:

double.go

package main

import "fmt"

func main() {
    result := double(3)
    fmt.Println(result)
}

func double(x int) int {
    y := x * 2
    // return y
}

现在,让我们再次运行程序:

go run double.go



Output

./double.go:13:1: missing return at end of function


此处不使用return语句,程序无法编译。

函数在遇到 return 语句时立即退出,即使它们不在函数末尾:

return_loop.go

package main

import "fmt"

func main() {
    loopFive()
}

func loopFive() {
    for i := 0; i < 25; i++ {
        fmt.Print(i)
        if i == 5 {
            // Stop function at i == 5
            return
        }
    }
    fmt.Println("This line will not execute.")
}

这里我们遍历一个 for 循环,并告诉循环运行 25 次迭代。但是,在 for 循环中,我们有一个条件 if 语句来检查 i 的值是否等于 5。如果是,我们发出一个 return 语句。因为我们在 loopFive 函数中,所以函数中任何点的任何返回都将退出该函数。结果,我们永远不会到达这个函数的最后一行来打印语句 这行将不会执行..

在 for 循环中使用 return 语句结束函数,因此循环外的行将不会运行。相反,如果我们使用了 break 语句,那么此时只有循环会退出,并且最后一行 fmt.Println() 会运行。

return 语句退出一个函数,如果在函数签名中指定,它可能会返回一个值。

返回多个值


一个函数可以指定多个返回值。让我们检查 repeat.go 程序并让它返回两个值。第一个将是重复值,如果 reps 参数不是大于 0 的值,则第二个将是错误:

return_loop.go

package main

import "fmt"

func main() {
    val, err := repeat("Sammy", -1)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(val)
}

func repeat(word string, reps int) (string, error) {
    if reps <= 0 {
        return "", fmt.Errorf("invalid value of %d provided for reps. value must be greater than 0.", reps)
    }
    var value string
    for i := 0; i < reps; i++ {
        value = value + word
    }
    return value, nil
}

repeat 函数所做的第一件事是检查 reps 参数是否为有效值。任何不大于 0 的值都会导致错误。由于我们传入了 -1 的值,这个代码分支就会执行。请注意,当我们从函数返回时,我们必须提供字符串和错误返回值。因为提供的参数导致错误,我们将为第一个返回值传回一个空白字符串,并为第二个返回值传回错误。

在 main() 函数中,我们可以通过声明两个新变量 value 和 err 来接收两个返回值。因为返回中可能有错误,我们想在继续我们的程序之前检查我们是否收到错误。在这个例子中,我们确实收到了一个错误。我们打印出错误并从 main() 函数中返回以退出程序。

如果没有错误,我们将打印出函数的返回值。

注意:最好只返回两个或三个值。此外,您应该始终将所有错误作为函数的最后一个返回值返回。

运行程序将产生以下输出:


Output

invalid value of -1 provided for reps. value must be greater than 0.


在本节中,我们回顾了如何使用 return 语句从函数返回多个值。

结论


函数是在程序中执行操作的指令代码块,有助于使我们的代码可重用和模块化。

文章链接