Go语言函数和包介绍

函数

什么是函数?

函数是执行特定任务的代码块。函数接受输入,对输入执行一些计算,然后生成输出。

通常每一个程序都包含有很多的函数,系统通过函数来划分不同功能,将整体任务进行分解。

在 Go 语言中,函数的基本组成包括:关键字 func、函数名、参数列表、返回值、函数体和返回语句。

Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回数组中包含的元素个数。

函数声明

在 go 中声明函数的语法是

func functionname(parametername type) returntype {  
 //function body
}

函数定义解析:

  • func:函数由 func 开始声明。
  • functionname:函数名称,函数名和参数列表一起构成了函数签名。
  • functionname type:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • returntype:返回类型,函数返回一列值。有些功能不需要返回值,这种情况下 returntype不是必须的。
  • 函数体:函数定义的代码集合。
示例函数

让我们编写一个函数,该函数将单个产品的价格和产品数量作为输入参数,并通过将这两个值相乘来计算总价格并返回输出。

func calculateBill(price int, no int) int {  
    var totalPrice = price * no
    return totalPrice
}

上面的函数有两个 int 类型的输入参数priceno它返回的totalPrice是价格和编号的乘积。返回值也是int类型。

如果连续的参数类型相同,就可以避免每次都写类型,最后写一次就可以了。即 price int, no int可以写为price, no int. 因此,上述函数可以重写为:

func calculateBill(price, no int) int {  
    var totalPrice = price * no
    return totalPrice
}

现在我们已经准备好了一个函数,让我们从代码中的某个地方调用它。调用函数的语法是functionname(parameters)。可以使用代码调用上述函数。

calculateBill(10, 5)  

这是使用上述函数并打印总价的完整程序。

package main

import (  
    "fmt"
)

func calculateBill(price, no int) int {  
    var totalPrice = price * no
    return totalPrice
}

func main() {  
    price, no := 90, 6
    totalPrice := calculateBill(price, no)
    fmt.Println("Total price is", totalPrice)
}

Run in playground

上面的程序会打印

Total price is 540  
多个返回值

一个函数可以返回多个值。让我们编写一个函数rectProps,它接受矩形的 lengthwidth并返回

长方形的面积->长和宽的乘积

周长->长和宽之和的两倍

package main

import (  
    "fmt"
)

func rectProps(length, width float64)(float64, float64) {  
    var area = length * width
    var perimeter = (length + width) * 2
    return area, perimeter
}

func main() {  
     area, perimeter := rectProps(10.8, 5.6)
    fmt.Printf("Area %f Perimeter %f", area, perimeter) 
}

Run in playground

如果函数返回多个返回值,则必须在(lengthwidth 它们之间指定)func rectProps(length, width float64)(float64, float64)有两个 float64 参数length and width并且还返回两个float64值。上面的程序打印出

Area 60.480000 Perimeter 32.800000  
命名返回值

可以从函数返回命名值。如果已命名返回值,则可以将其视为在函数的第一行中声明为变量。

上面的 rectProps 可以使用命名的返回值重写为

func rectProps(length, width float64)(area, perimeter float64) {  
    area = length * width
    perimeter = (length + width) * 2
    //无显式返回值
    return 
}

面积周长是上述函数中的命名返回值。请注意,函数中的 return 语句不会显式返回任何值。由于 和 在函数声明中指定为返回值,因此在遇到 return 语句时会自动从函数返回它们。areaperimeter

空白标识符

**_**在 Go 中称为空白标识符。它可以代替任何类型的任何值。让我们看看这个空白标识符有什么用。

该函数返回矩形的面积和周长。如果我们只需要 面积并想丢弃周长.这就是用处。area _

参考下面的程序

package main

import (  
    "fmt"
)

func rectProps(length, width float64) (float64, float64) {  
    var area = length * width
    var perimeter = (length + width) * 2
    return area, perimeter
}
func main() {  
    area, _ := rectProps(10.8, 5.6) // perimeter is discarded
    fmt.Printf("Area %f ", area)
}

Run in playground

Area 60.480000 

什么是包,为什么使用它们?

到目前为止,我们已经看到 Go 程序只有一个包含一个 main函数和几个其他函数的文件。在现实场景中,这种将所有源代码写入单个文件的方法是不可扩展的。重用和维护以这种方式编写的代码变得不可能。这就是包的用处。

包用于组织 Go 源代码,以提高可重用性和可读性。包是驻留在同一目录中的 Go 源文件的集合。包提供了代码划分,因此维护 Go 项目变得很容易。

演示图例

在这里插入图片描述

Go 模块

Go 模块只不过是 Go 包的集合。现在你可能会想到这个问题。为什么我们需要 Go 模块来创建自定义包?答案是我们创建的自定义包的导入路径派生自 go 模块的名称。除此之外,我们的应用程序使用的所有其他第三方软件包(例如来自 github 的源代码)将与版本一起出现在文件中。此文件是在我们创建新模块时创建的。您将在下一节中更好地理解这一点。

cd learnpackage 目录下
//执行
go mod init learnpackage  

上面的命令将创建一个名为go.mod的文件,以下是文件的内容。

module learnpackage

go 1.21.0

我们创建simpleinterest文件夹,在创建一个simpleinterest.go文件

package simpleinterest

//计算并返回本金p的单利,利率r的时间跨度为t年
func Calculate(p float64, r float64, t float64) float64 {  
    interest := p * (r / 100) * t
    return interest
}

在上面的代码中,我们创建了一个计算并返回简单利息的函数Calculate。此功能是计算并返回单利。

请注意,函数名称 Compute 以大写字母开头。这是必不可少的

导入自定义包

要使用自定义包,我们必须先导入它。导入路径是附加在包的子目录和包名称上的模块名称。在我们的例子中,模块名称是learnpackage,包在直接位于下面的文件夹中的simpleinterest
目前项目目录:
在这里插入图片描述

导入simpleinterest
在这里插入图片描述

上面的代码导入包并使用函数查找单利。标准库中的包不需要模块名称前缀,因此“fmt”在没有模块前缀的情况下工作。当应用程序运行时,输出将是`

Simple interest calculation  
Simple interest is 500  
初始化函数

Go 中的每个包都可以包含一个函数。该函数不得具有任何返回类型,并且不得具有任何参数。init 函数不能在我们的源代码中显式调用。初始化包时将自动调用它。初始化函数具有以下语法init``init

func init() {  
}

该函数可用于执行初始化任务,也可用于在执行开始之前验证程序的正确性。init

包的初始化顺序如下

  1. 首先初始化包级变量
  2. 接下来调用初始化函数。包可以有多个 init 函数(在单个文件中或分布在多个文件中),并且按照它们呈现给编译器的顺序调用它们。

如果包导入其他包,则首先初始化导入的包。

即使从多个包导入包,也只会初始化一次包。

让我们对应用程序进行一些修改以了解函数。init

首先,让我们将函数添加到文件中。init``simpleinterest.go

package simpleinterest

import "fmt"

/*
 * 新增Init功能
 */
func init() {
	fmt.Println("初始化  simpleinterest")
}

// 计算并返回本金p的单利,利率r的时间跨度为t年interest r for time duration t years
func Calculate(p float64, r float64, t float64) float64 {
	interest := p * (r / 100) * t
	return interest
}

我们添加了一个简单的初始化函数

现在让我们修改主包。我们知道,在计算单利时,本金、利率和持续时间应大于零。我们将在文件中使用 init 函数和包级变量来定义此检查。main.go

将 修改为以下内容,main.go

package main

import (
	"fmt"
	"learnpackage/simpleinterest"
)

func init() {
	fmt.Println("初始化  main")
}

var p, r, t = 5000.0, 10.0, 1.0

func main() {
	fmt.Println("简单利息计算")
	si := simpleinterest.Calculate(p, r, t)
	fmt.Println("单利是", si)
}


以下是对main.go

  1. PRT 变量从主函数级别移动到包级别。
  2. 添加了初始化函数。init 函数使用 log 打印日志并在本金、利率或持续时间小于零时终止程序执行**。致命**功能。

初始化的顺序如下:

  1. 首先初始化导入的包。因此,首先初始化 simpleinterest 包,并调用它的 init 方法。
  2. 接下来初始化包级变量 prt
  3. 初始化函数在 main 中调用。
  4. 最后调用主函数。

如果运行该程序,将获得以下输出。

初始化  simpleinterest
初始化  main
简单利息计算
单利是 500  
使用空白标识符

在 Go 中导入包而不在代码中的任何位置使用它都是非法的。如果您这样做,编译器将报错。这样做的原因是为了避免未使用的包膨胀,这将显着增加编译时间。将 main.go中的代码替换为以下内容,

package main

import (  
        "learnpackage/simpleinterest"
)

func main() {

}

上述程序将出错

# learnpackage
./main.go:4:2: imported and not used: "learnpackage/simpleinterest"

但是,在应用程序处于积极开发状态时导入包并在以后(如果不是现在)在代码中的某个位置使用它们是很常见的。在这些情况下,空白标识符可以拯救我们。_

package main

import (  
    _ "learnpackage/simpleinterest"
)

func main() {

}

运行上述程序将输出 。我们已经成功初始化了包,即使它没有在代码中的任何位置使用。

在这里插入图片描述
上一教程 Go语言常量介绍
下一教程 Go语言条件语句

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值