学习 Go,一段旅程:标准库包和并发 #5
作者:互联网
学习 Go,一段旅程:标准库包和并发 #5
大家好!很高兴再次见到你,我希望你做得很好。在本文中,我想分享我在学习 Go 编程语言方面的进展。本周,我了解了标准库包和并发。
标准库包
我们已经了解了基本的 Go 编程语言,现在我们将学习如何将我们的代码集成到标准库包中,例如 JSON、sort 和 bcrypt。
JSON
JSON 或 Javascript Object Notation 是一种用于在 Web 应用程序中传输数据的格式(例如,将数据发送到客户端,以便在网页上显示)。在 Go 中,我们可以使用 编码/json 包从 JSON 转换为结构,反之亦然。我们可以使用 2 个函数:
- JSON元帅
Marshal 返回一个字节切片中值的 JSON 编码,如果有则返回错误。
例如,我们有一个结构并希望将其编码为 JSON,以便我们可以将其发送到客户端(例如 Web 应用程序)
从上图中,我们可以导入 JSON 包并通过传递一个切片类型的参数来调用函数 marshal。封送函数返回 2 个值、编码值和一个错误。所以我们必须检查是否有任何错误发生。如果没有错误,我们可以用字符串函数再次转换,因为一个编组函数返回一个字节切片。之后,我们可以将数据发送到客户端(例如 Web 应用程序)
- JSON 解组
元帅与元帅相反。 Unmarshal 解析 JSON 编码的数据并将结果存储在 v 指向的值中。Unmarshal 函数接收 2 个参数,一个具有字节切片类型的数据和一个值。请注意,我强调了指向这个词,因为 unmarshal 函数只接收具有指针类型的值。函数返回只返回一个错误。
例如,我们有一个来自客户端的 JSON 格式的请求。要处理数据,我们必须先将其解析为切片。
首先,我们收到一个字符串类型的请求。从那个请求中,我们需要知道数据结构。请求有键值对,每个字段都有不同的数据类型,所以我们要根据请求创建一个结构体。之后,我们将字符串转换为字节切片。然后,创建一个类型为 secretAgent 的变量。然后,通过传递 2 个参数调用 unmarshal 函数,即 byteRequest 和我们想要存储解析数据的变量(它必须是一个指针,所以我放了一个 & 运算符)。 Unmarshal 会返回一个错误,所以我们必须检查它是否有任何错误。最后一件事,打印解析后的数据。
种类
包排序提供了对切片和用户定义的集合进行排序的原语。
- 对整数切片进行排序
为了对整数切片进行排序,我们可以使用 Ints(x []int) 函数。它将按递增顺序对一片整数进行排序
- 对一段字符串进行排序
为了对字符串切片进行排序,我们可以使用 Strings(x []string) 函数。它将按升序对一段字符串进行排序
- 自定义排序
之前,我们已经知道如何按升序对整数或字符串进行排序。那么如果我们想按降序对它进行排序呢?我们可以使用一个接收 2 个参数的切片函数、一个切片和一个自定义函数来确定升序或降序。
使用 slice 函数,我们还可以根据任何键对结构切片进行排序。例如
加密货币
加密和散列之间是有区别的。加密是一种双向功能,包括加密和解密,而散列是将纯文本更改为不可逆的唯一摘要的单向功能。 Go 中的 bcrypt 包实现了 Provos 和 Mazières 的 bcrypt 自适应哈希算法。要在我们的项目中使用 bcrypt 包,我们必须首先在 bash 或终端中使用此语法安装它
之后,我们可以在我们的项目中使用它。我们需要查看 2 个函数
- 从密码生成
此函数生成一个散列密码。它以给定的代价返回密码的 bcrypt 哈希值和一个错误。成本基本上决定了哈希算法的复杂程度。
例如
由于该函数返回一个字节切片,因此我们必须使用字符串函数将其转换为字符串。
- 比较哈希和密码
此函数将 bcrypt 散列密码与其可能的明文等效密码进行比较。如果成功或错误,则返回 nil。
例如
如上图所示,我们比较了 2 个密码,它们是散列的“password123”和文本“password1243”。该函数返回错误,因为它不同。
并发
在计算机科学中,并发性是程序、算法或问题的不同部分或单元在不影响最终结果的情况下无序或按部分顺序执行的能力。
Go 中的并发
2006年,英特尔向世界推出了第一款多核处理器。 2007 年,Google 开始开发 Go 编程语言,所以默认情况下,Go 编程语言是自适应并发模式的。 Go 有一个名为 goroutines 的内置函数,它能够拆分任务并运行并发程序。要调用 goroutine,我们使用“go”关键字。
正如我们所见,我们有两个函数可以打印出“Hello”和“World”这两个词。我们将 foo 函数启动到另一个 goroutine 中。所以理论上我们有 2 个 goroutine 同时运行(一个运行 main 函数,另一个运行 foo 函数)。但是输出只显示了“Hello”这个词,这是怎么回事?基本上,程序在运行 foo 函数之前退出(主 goroutine)。如果我们再次尝试运行它,有时它会在 foo 函数运行的地方显示不同的结果。例如
上图显示了 foo 函数在主 goroutine 退出之前运行。
等待组
从上面的讨论中,我们发现了一个问题,即我们的代码在完成所有任务之前就完成了。为了解决这个问题,我们可以使用包同步中的 WaitGroup。 WaitGroup 等待一组不同的 goroutine 完成它们的任务。例如
从上图中可以看出,WaitGroup Add(delta int)、Done() 和 Wait() 有 3 个函数。 Add(delta int) 意味着我们在等待列表中添加 1 个等待的 goroutine,我们可以输入任何我们想要的数字(如果它是负数,它会引发恐慌)。 Done() 意味着当 goroutine 完成其任务时,它将增加 Add 函数中的等待列表。 Wait() 意味着它会等到所有的 goroutine 完成他们的任务。
比赛条件
竞争条件是程序覆盖相同变量的条件。例如
从上图中我们可以看到,我们启动了一个新的 goroutine,每次循环迭代都会增加 1 个值。理论上,当我们打印出计数器变量时,它应该是 10。但是我们有一个竞争条件,要检查我们是否有任何竞争条件,我们可以使用这个命令。
互斥体
那么如何解决竞态条件呢?我们可以使用互斥锁。互斥锁是互斥锁。例如
从上图中,我们在函数将 counter 变量加 1 时锁定。这意味着另一个 goroutine 不能使用它们之间共享的变量,直到使用它的那个完成它的任务。如果我们检查任何竞争条件,结果显示无
原子
避免任何竞争条件的另一种方法是使用原子。例如
如果我们检查任何竞争条件,结果显示无
这篇文章就到这里了,别忘了点个赞分享给更多人。如果您有任何反馈,如果您在下面发表评论,我会很高兴。感谢您阅读本文,祝您有美好的一天。
资源
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
本文链接:https://www.qanswer.top/11878/00570401
标签:函数,旅程,goroutine,切片,JSON,Go,我们,库包 来源: https://www.cnblogs.com/amboke/p/16654114.html