如何在Go中定义和调用函数

介绍 (Introduction)

A function is a section of code that, once defined, can be reused. Functions are used to make your code easier to understand by breaking it into small, understandable tasks that can be used more than once throughout your program.

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

Go ships with a powerful standard library that has many predefined functions. Ones that you are probably already familiar with from the fmt package are:

Go附带了功能强大的标准库,该库具有许多预定义功能。 您可能已经从fmt包中熟悉的是:

  • fmt.Println() which will print objects to standard out (most likely your terminal).

    fmt.Println()会将对象打印为标准输出(很可能是您的终端)。

  • fmt.Printf() which will allow you to format your printed output.

    fmt.Printf()它将允许您格式化打印输出。

Function names include parentheses and may include parameters.

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

In this tutorial, we’ll go over how to define your own functions to use in your coding projects.

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

定义功能 (Defining a Function)

Let’s start with turning the classic “Hello, World!” program into a function.

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

We’ll create a new text file in our text editor of choice, and call the program hello.go. Then, we’ll define the function.

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

A function is defined by using the func keyword. This is then followed by a name of your choosing and a set of parentheses that hold any parameters the function will take (they can be empty). The lines of function code are enclosed in curly brackets {}.

通过使用func关键字定义func 。 然后是您选择的名称和一组括号,这些括号包含函数将采用的所有参数(它们可以为空)。 功能代码行括在大括号{}

In this case, we’ll define a function named hello():

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

hello.go
你好
func hello() {}

This sets up the initial statement for creating a function.

这将建立用于创建函数的初始语句。

From here, we’ll add a second line to provide the instructions for what the function does. In this case, we’ll be printing Hello, World! to the console:

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

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

Our function is now fully defined, but if we run the program at this point, nothing will happen since we didn’t call the function.

现在已经完全定义了函数,但是如果此时运行程序,则由于未调用函数,因此不会发生任何事情。

So, inside of our main() function block, let’s call the function with hello():

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

hello.go
你好
package main

import "fmt"

func main() {
    hello()
}

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

Now, let’s run the program:

现在,让我们运行程序:

  • go run hello.go

    去跑hello.go

You’ll receive the following output:

您将收到以下输出:


   
   
Output
Hello, World!

Notice that we also introduced a function called main(). The main() function is a special function that tells the compiler that this is where the program should start. For any program that you want to be executable (a program that can be run from the command line), you will need a main() function. The main() function must appear only once, be in the main() package, and receive and return no arguments. This allows for program execution in any Go program. As per the following example:

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

main.go
main.go
package main

import "fmt"

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

Functions can be more complicated than the hello() function we defined. We can use for loops, conditional statements, and more within our function block.

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

For example, the following function uses a conditional statement to check if the input for the name variable contains a vowel, then uses a for loop to iterate over the letters in the name string.

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

names.go
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.")
}

The names() function we define here sets up a name variable with input, and then sets up a conditional statement within a for loop. This shows how code can be organized within a function definition. However, depending on what we intend with our program and how we want to set up our code, we may want to define the conditional statement and the for loop as two separate functions.

我们在此处定义的names()函数使用输入设置name变量,然后在for循环中设置条件语句。 这显示了如何在函数定义中组织代码。 但是,根据我们对程序的期望以及如何设置代码,我们可能希望将条件语句和for循环定义为两个单独的函数。

Defining functions within a program makes our code modular and reusable so that we can call the same functions without rewriting them.

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

使用参数 (Working with Parameters)

So far we have looked at functions with empty parentheses that do not take arguments, but we can define parameters in function definitions within their parentheses.

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

A parameter is a named entity in a function definition, specifying an argument that the function can accept. In Go, you must specify the data type for each parameter.

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

Let’s create a program that repeats a word a specified number of times. It will take a string parameter called word and an int parameter called reps for the number of times to repeat the word.

让我们创建一个程序,该程序将单词重复指定的次数。 重复单词的次数将包含一个名为wordstring参数和一个名为repsint参数。

repeat.go
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)
    }
}

We passed the value Sammy in for the word parameter, and 5 for the reps parameter. These values correspond with each parameter in the order they were given. The repeat function has a for loop that will iterate the number of times specified by the reps parameter. For each iteration, the value of the word parameter is printed.

我们通过价值Sammy中的word参数,以及5reps的参数。 这些值按照给定的顺序与每个参数相对应。 repeat函数具有一个for循环,该循环将迭代reps参数指定的reps 。 对于每次迭代,都会打印word参数的值。

Here is the output of the program:

这是程序的输出:


   
   
Output
SammySammySammySammySammy

If you have a set of parameters that are all the same value, you can omit specifying the type each time. Let’s create a small program that takes in parameters x, y, and z that are all int values. We’ll create a function that adds the parameters together in different configurations. The sums of these will be printed by the function. Then we’ll call the function and pass numbers into the function.

如果一组参数都具有相同的值,则可以每次省略指定类型。 让我们创建一个小程序,该程序接受所有均为int值的参数xyz 。 我们将创建一个将参数添加到不同配置中的函数。 这些的总和将由函数打印。 然后,我们将调用该函数并将数字传递给该函数。

add_numbers.go
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)
}

When we created the function signature for addNumbers, we did not need to specify the type each time, but only at the end.

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

We passed the number 1 in for the x parameter, 2 in for the y parameter, and 3 in for the z parameter. These values correspond with each parameter in the order they are given.

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

The program is doing the following math based on the values we passed to the parameters:

该程序基于我们传递给参数的值进行以下数学运算:

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

The function also prints a, b, and c, and based on this math we would expect a to be equal to 3, b to be 4, and c to be 5. Let’s run the program:

该函数还会打印abc ,并且根据此数学公式,我们希望a等于3b等于4c等于5 。 让我们运行程序:

  • go run add_numbers.go

    去运行add_numbers.go

   
   
Output
3 4 5

When we pass 1, 2, and 3 as parameters to the addNumbers() function, we receive the expected output.

当我们通过12 ,和3作为参数传递给addNumbers()函数中,我们得到预期的输出。

Parameters are arguments that are typically defined as variables within function definitions. They can be assigned values when you run the method, passing the arguments into the function.

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

返回值 (Returning a Value)

You can pass a parameter value into a function, and a function can also produce a value.

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

A function can produce a value with the return statement, which will exit a function and optionally pass an expression back to the caller. The return data type must be specified as well.

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

So far, we have used the fmt.Println() statement instead of the return statement in our functions. Let’s create a program that instead of printing will return a variable.

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

In a new text file called double.go, we’ll create a program that doubles the parameter x and returns the variable y. We issue a call to print the result variable, which is formed by running the double() function with 3 passed into it:

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

double.go
double.go
package main

import "fmt"

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

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

We can run the program and see the output:

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

  • go run double.go

    去跑double.go

   
   
Output
6

The integer 6 is returned as output, which is what we would expect by multiplying 3 by 2.

整数6作为输出返回,这是我们将3乘以2

If a function specifies a return, you must provide a return as part of the code. If you do not, you will receive a compilation error.

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

We can demonstrate this by commenting out the line with the return statement:

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

double.go
double.go
package main

import "fmt"

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

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

Now, let’s run the program again:

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

  • go run double.go

    去跑double.go

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

Without using the return statement here, the program cannot compile.

如果不使用return语句,程序将无法编译。

Functions exit immediately when they hit a return statement, even if they are not at the end of the function:

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

return_loop.go
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.")
}

Here we iterate through a for loop, and tell the loop to run 25 iterations. However, inside the for loop, we have a conditional if statement that checks to see if the value of i is equal to 5. If it is, we issue a return statement. Because we are in the loopFive function, any return at any point in the function will exit the function. As a result, we never get to the last line in this function to print the statement This line will not execute..

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

Using the return statement within the for loop ends the function, so the line that is outside of the loop will not run. If, instead, we had used a break statement, only the loop would have exited at that time, and the last fmt.Println() line would run.

for循环内使用return语句会终止该函数,因此循环外的行将不会运行。 相反,如果我们使用了break语句 ,那么到那时只有循环会退出,最后的fmt.Println()行将运行。

The return statement exits a function, and may return a value if specified in the function signature.

return语句退出一个函数,并且如果在函数签名中指定,则可以返回一个值。

返回多个值 (Returning Multiple Values)

More than one return value can be specified for a function. Let’s examine the repeat.go program and make it return two values. The first will be the repeated value and the second will be an error if the reps parameter is not a value greater than 0:

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

repeat.go
repeat.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
}

The first thing the repeat function does is check to see if the reps argument is a valid value. Any value that is not greater than 0 will cause an error. Since we passed in the value of -1, this branch of code will execute. Notice that when we return from the function, we have to provide both the string and error return values. Because the provided arguments resulted in an error, we will pass back a blank string for the first return value, and the error for the second return value.

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

In the main() function, we can receive both return values by declaring two new variables, value and err. Because there could be an error in the return, we want to check to see if we received an error before continuing on with our program. In this example, we did receive an error. We print out the error and return out of the main() function to exit the program.

main()函数中,我们可以通过声明两个新变量valueerr来接收两个返回值。 由于返回中可能存在错误,因此我们希望在继续执行程序之前检查是否收到错误。 在这个例子中,我们确实收到了一个错误。 我们打印出错误并return该出main()函数退出程序。

If there was not an error, we would print out the return value of the function.

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

Note: It is considered best practice to only return two or three values. Additionally, you should always return all errors as the last return value from a function.

注意:最佳做法是仅返回两个或三个值。 此外,您应始终将所有错误作为函数的最后一个返回值返回。

Running the program will result in the following output:

运行该程序将得到以下输出:


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

In this section we reviewed how we can use the return statement to return multiple values from a function.

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

结论 (Conclusion)

Functions are code blocks of instructions that perform actions within a program, helping to make our code reusable and modular.

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

To learn more about how to make your code more modular, you can read our guide on How To Write Packages in Go.

要了解有关如何使代码更具模块化的更多信息,可以阅读有关如何在Go中编写包的指南。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-define-and-call-functions-in-go

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值