【Go语言开发】了解 Go 中的包的可见性
介绍
在 Go 中创建包时,最终目标通常是使包可供其他开发人员使用,无论是高阶包还是整个程序。通过导入包,您的代码可以作为其他更复杂工具的构建块。但是,只有某些包可用于导入。这是由包的可见性决定的。
在此上下文中的可见性意味着可以引用包或其他构造的文件空间。例如,如果我们在函数中定义一个变量,该变量的可见性(范围)仅在定义它的函数内。同样,如果您在包中定义变量,则可以使其仅对该包可见,或者也允许它在包外可见。
在编写符合人体工程学的代码时,仔细控制包的可见性很重要,尤其是在考虑到您可能希望对包进行的未来更改时。如果您需要修复错误、提高性能或更改功能,您需要以不会破坏任何使用您的包的人的代码的方式进行更改。最小化重大更改的一种方法是只允许访问包中正确使用它所需的部分。通过限制访问,您可以在内部对您的包进行更改,而不会影响其他开发人员如何使用您的包。
在本文中,您将学习如何控制包的可见性,以及如何保护只应在包内使用的部分代码。为此,我们将创建一个基本的记录器来记录和调试消息,使用具有不同程度项目可见性的包。
先决条件
要遵循本文中的示例,您将需要:
【Go语言开发】理解 Go 中的延迟(defer )
介绍
Go 有许多其他编程语言中常见的控制流关键字,例如 if、switch、for 等。大多数其他编程语言中没有的一个关键字是 defer,虽然它不太常见,但您很快就会看到它在您的程序中有多大用处。
defer 语句的主要用途之一是清理资源,例如打开的文件、网络连接和数据库句柄。当您的程序使用完这些资源后,关闭它们以避免耗尽程序的限制并允许其他程序访问这些资源非常重要。 defer 通过将关闭文件/资源的调用保持在打开调用附近,使我们的代码更清晰,更不容易出错。
在本文中,我们将学习如何正确使用 defer 语句来清理资源以及使用 defer 时常犯的几个错误。
什么是延迟(defer
)声明
defer 语句将 defer 关键字后面的函数调用添加到堆栈中。当添加它们的函数返回时,调用该堆栈上的所有调用。因为调用被放置在堆栈上,所以它们以后进先出的顺序被调用。
让我们通过打印一些文本来看看 defer 是如何工作的:
main.go
【Go语言基础】理解 Go 中的 init
介绍
在 Go 中,预定义的 init() 函数会启动一段代码,以便在包的任何其他部分之前运行。此代码将在导入包后立即执行,并且可以在您需要应用程序在特定状态下初始化时使用,例如当您具有特定配置或应用程序需要启动的一组资源时。导入副作用时也使用它,这是一种通过导入特定包来设置程序状态的技术。这通常用于将一个包注册到另一个包,以确保程序正在考虑任务的正确代码。
尽管 init() 是一个有用的工具,但它有时会使代码难以阅读,因为难以找到的 init() 实例会极大地影响代码的运行顺序。因此,对于刚接触 Go 的开发人员来说,了解这个函数的各个方面非常重要,这样他们才能确保在编写代码时以清晰的方式使用 init()。
在本教程中,您将了解如何使用 init() 来设置和初始化特定包变量、一次计算以及注册一个包以与另一个包一起使用。
先决条件
对于本文中的一些示例,您将需要:
【Go语言高级开发】理解 Go 中的指针
介绍
当你用 Go 编写软件时,你将编写函数和方法。您将数据作为参数传递给这些函数。有时,该函数需要数据的本地副本,而您希望原始数据保持不变。例如,如果您是一家银行,并且您有一个功能可以根据用户选择的储蓄计划向用户显示他们的余额变化,那么您不希望在客户选择计划之前更改他们的实际余额;您只想在计算中使用它。这称为按值传递,因为您将变量的值发送给函数,而不是变量本身。
其他时候,您可能希望函数能够更改原始变量中的数据。例如,当银行客户向他们的账户存款时,您希望存款功能能够访问实际余额,而不是副本。在这种情况下,您不需要将实际数据发送给函数;你只需要告诉函数数据在内存中的位置。称为指针的数据类型保存数据的内存地址,但不保存数据本身。内存地址告诉函数在哪里找到数据,而不是数据的值。您可以将指针传递给函数而不是数据,然后函数可以就地更改原始变量。这被称为通过引用传递,因为变量的值并没有传递给函数,只是它的位置。
在本文中,您将创建和使用指针来共享对变量内存空间的访问。
【Go语言开发】如何在 Go 中为错误添加额外信息
介绍
当 Go 中的函数失败时,该函数将使用错误接口返回一个值,以允许调用者处理该失败。在很多情况下,开发者会使用 fmt 包中的 fmt.Errorf 函数来返回这些值。但是,在 Go 1.13 之前,使用此函数的一个缺点是您会丢失有关可能导致返回错误的任何错误的信息。为了解决这个问题,开发人员要么使用包来提供一种将错误“包装”在其他错误中的方法,要么通过在他们的一种结构错误类型上实现 Error() 字符串方法来创建自定义错误。但是,如果您有许多不需要由调用者显式处理的错误,有时创建这些结构类型可能会很乏味,因此在 Go 1.13 中,该语言添加了一些功能以更容易处理这些情况。
一项功能是能够使用 fmt.Errorf 函数包装错误,该函数具有一个错误值,该错误值可以在以后解包以访问已包装的错误。这将错误包装功能构建到 Go 标准库中,因此不再需要使用第三方库。
此外,函数 errors.Is 和 errors.As 可以更容易地确定特定错误是否包含在给定错误中的任何位置,并且还可以让您直接访问该特定错误,而无需自己解开所有错误。
在本教程中,您将创建一个程序,该程序使用这些函数在从函数返回的错误中包含附加信息,然后创建您自己的支持包装和展开功能的自定义错误结构。
【Go语言开发】如何在 Go 中使用上下文
介绍
在开发大型应用程序时,尤其是在服务器软件中,有时除了函数独立运行所需的信息之外,了解更多关于它正在执行的环境的信息是有帮助的。例如,如果 Web 服务器函数正在处理特定客户端的 HTTP 请求,则该函数可能只需要知道客户端请求哪个 URL 来提供响应。该函数可能只将该 URL 作为参数。但是,在提供响应时总是会发生一些事情,例如客户端在收到响应之前断开连接。如果提供响应的函数不知道客户端已断开连接,则服务器软件最终可能会花费比计算永远不会使用的响应所需的更多计算时间。
在这种情况下,了解请求的上下文,例如客户端的连接状态,允许服务器在客户端断开连接后停止处理请求。这可以在繁忙的服务器上节省宝贵的计算资源,并释放它们来处理另一个客户端的请求。这种类型的信息在函数执行需要时间的其他上下文中也很有帮助,例如进行数据库调用。为了使对此类信息的普遍访问成为可能,Go 在其标准库中包含了一个上下文包。
在本教程中,您将首先创建一个在函数中使用上下文的 Go 程序。然后,您将更新该程序以在上下文中存储附加数据并从另一个函数中检索它。最后,您将使用上下文的能力来表示它已完成以停止处理其他数据。
先决条件
【Go语言基础】如何在Golang中使用JSON
介绍
在现代程序中,一个程序和另一个程序之间的通信很重要。无论是检查用户是否可以访问另一个程序的 Go 程序、获取显示在网站上的过去订单列表的 JavaScript 程序,还是从文件中读取测试结果的 Rust 程序,程序都需要一种方法来为其他程序提供数据。然而,许多编程语言都有自己的内部存储数据的方式,这是其他语言无法理解的。为了允许这些语言进行交互,需要将数据转换为他们都能理解的通用格式。其中一种格式 JSON 是一种通过 Internet 以及在同一系统中的程序之间传输数据的流行方式。
许多现代编程语言在其标准库中包含一种将数据与 JSON 相互转换的方法,Go 也是如此。通过使用 Go 提供的 encoding/json 包,您的 Go 程序还可以与任何其他可以使用 JSON 进行通信的系统进行交互。
在本教程中,您将首先创建一个程序,该程序使用 encoding/json 包将地图中的数据编码为 JSON 数据,然后更新您的程序以使用结构类型对数据进行编码。之后,您将更新您的程序以将 JSON 数据解码为映射,然后最终将 JSON 数据解码为结构类型。
先决条件
要遵循本教程,您将需要:
【Go语言Web开发】如何在Go中创建HTTP服务器
介绍
许多开发人员至少花了一些时间来创建服务器,以便在互联网上分发内容。超文本传输协议(HTTP)提供了大部分内容,无论是对猫图像的请求还是加载您正在阅读的教程的请求。Go标准库提供了内置支持,用于创建一个HTTP服务器来服务您的web内容或向这些服务器发出HTTP请求。
在本教程中,您将使用Go的标准库创建一个HTTP服务器,然后扩展服务器以从请求的查询字符串、正文和表单数据中读取数据。您还将更新程序,以使用自己的HTTP头和状态代码响应请求。
先决条件
要遵循本教程,您需要:
【Go语言高级开发】如何在Go中并发运行多个函数
介绍
Go语言的一个流行特性是它对并发性的一流支持,或者说一个程序同时做多件事情的能力。随着计算机从更快地运行单个代码流转向同时运行更多代码流,能够并发运行代码正成为编程的一个重要部分。为了更快地运行程序,程序员需要设计并发运行的程序,以便程序的每个并发部分可以独立于其他部分运行。Go中的两个特性,goroutines和channel,在一起使用时使并发更容易。Goroutines解决了在程序中设置和运行并发代码的困难,通道解决了并发运行的代码之间安全通信的困难。
在本教程中,您将探索goroutines和频道。首先,您将创建一个使用goroutines同时运行多个函数的程序。然后,您将向该程序添加通道,以便在运行的goroutines之间进行通信。最后,您将向程序中添加更多的goroutine,以模拟使用多个辅助goroutines运行的程序。
先决条件
要遵循本教程,您需要:
【Go语言基础】如何在Go语言中使用日期和时间
介绍
软件旨在使工作更容易完成,对许多人来说,这包括与日期和时间交互。日期和时间值在现代软件中随处可见。例如,跟踪汽车何时需要维修并让车主知道,跟踪数据库中的更改以创建审核日志,或者只是将一个时间与另一个时间进行比较以确定一个过程需要多长时间。因此,检索当前时间、操纵时间值以从中提取信息,并以易于理解的格式将其显示给用户是应用程序的基本属性。
在本教程中,您将创建一个Go程序来获取计算机的当前本地时间,然后以更易于阅读的格式将其打印到屏幕上。接下来,您将解释一个字符串以提取日期和时间信息。您还将转换两个时区之间的日期和时间值,以及加减时间值以确定两个时间之间的间隔。
先决条件
要遵循本教程,您需要:
- 安装1.16或更高版本。要设置此设置,请遵循操作系统的“如何安装Go”教程。
获取当前时间
在本节中,您将使用Go的时间包获得当前时间。Go标准库中的时间包提供了各种与日期和时间相关的函数,可以用来表示使用时间的特定时间点。时间类型。除了时间和日期,它还可以保存有关所表示的日期和时间所在的时区的信息。