通过示例学习-Go-语言-2023-七-
通过示例学习 Go 语言 2023(七)
Go(Golang)中的内层/外层作用域常量
目录
-
概述
-
示例
概述
在内层作用域中声明的常量,如果与外层作用域中声明的常量同名,将会遮蔽外层作用域中的常量。
示例
package main
import "fmt"
const a = 123
func main() {
const a = 456
fmt.Println(a)
}
输出
456
上述程序的输出为 456,因为内层声明的常量具有该值
Go (Golang) 中的常量映射
目录
-
概述
-
示例
概述
Go 仅支持四种类型的常量
-
数值(int, int64, float, float64, complex128 等)
-
字符串
-
字符或符文
-
布尔值
Go 不支持常量映射,因此以下程序会引发编译错误
示例
package main
func main() {
const e = map[string]int{
"a": 1,
}
}
输出
const initializer map[string]int literal is not a constant
在 Go (Golang)中从后序和中序构建二叉树
来源:
golangbyexample.com/binary-tree-postorder-inorder-golang/
目录
-
概述
-
程序
概述
给定两个数组,表示二叉树的后序和中序遍历。目标是从中构建二叉树
示例:
考虑下面的树
树的后序遍历将是
[1,2,4,3,5,6]
树的中序遍历将是
[4,2,1,5,3,6]
将提供后序和中序数组,我们必须再次从中序和后序构建树。以下将是策略
-
我们将使用三个索引,即数组的开始、结束和当前索引
-
后序中的最后一个索引将是根节点。
-
我们将在中序数组中查找与后序数组最后一个索引的值匹配的索引。我们将此索引称为 rootIndex
-
在中序数组中,rootIndex 左侧的所有值将位于左子树中
-
在中序数组中,rootIndex 右侧的所有值将位于右子树中
-
我们可以使用相同的策略递归处理右子树,然后处理左子树。
例如
-
后序遍历中的最后一个索引是根节点,其值为 1
-
值 1 在中序遍历中的 第 2 个索引。因此,rootIndex 是 2
-
在中序遍历中,rootIndex 左侧的部分是 [4,2],它是左子树的一部分
-
在中序遍历中,rootIndex 右侧是 [5,3,6],它是右子树的一部分
-
我们可以递归处理右子树,然后处理左子树
程序
以下是相应的程序
package main
import (
"fmt"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func buildTree(inorder []int, postorder []int) *TreeNode {
lenTree := len(inorder)
index := lenTree - 1
return buildTreeUtil(inorder, postorder, &index, 0, lenTree-1)
}
func buildTreeUtil(inorder []int, postorder []int, index *int, low, high int) *TreeNode {
if low > high {
return nil
}
if low == high {
currentIndexValue := postorder[*index]
(*index)--
return &TreeNode{Val: currentIndexValue}
}
currentIndexValue := postorder[*index]
(*index)--
root := &TreeNode{Val: currentIndexValue}
mid := 0
for i := low; i <= high; i++ {
if inorder[i] == currentIndexValue {
mid = i
}
}
root.Right = buildTreeUtil(inorder, postorder, index, mid+1, high)
root.Left = buildTreeUtil(inorder, postorder, index, low, mid-1)
return root
}
func main() {
inorder := []int{4, 2, 1, 5, 3, 6}
postorder := []int{4, 2, 5, 6, 3, 1}
root := buildTree(inorder, postorder)
fmt.Printf("root: %d\n", root.Val)
fmt.Printf("root.Left: %d\n", root.Left.Val)
fmt.Printf("root.Left.Left: %d\n", root.Left.Left.Val)
fmt.Printf("root.Right: %d\n", root.Right.Val)
fmt.Printf("root.Right.Left: %d\n", root.Right.Left.Val)
fmt.Printf("root.Right.Right: %d\n", root.Right.Right.Val)
}
输出
root: 1
root.Left: 2
root.Left.Left: 4
root.Right: 3
root.Right.Left: 5
root.Right.Right: 6
注意: 查看我们的 Golang 高级教程。本系列的教程详细且我们已尝试用示例涵盖所有概念。这个教程适合那些希望获得专业知识和对 golang 有扎实理解的人 - Golang 高级教程
如果你有兴趣了解所有设计模式如何在 Golang 中实现。如果是的话,这篇文章适合你 - 所有设计模式 Golang*
从先序和中序在 Go (Golang)中构造二叉树
目录
-
概述
-
程序
概述
给定两个数组,它们表示一个二叉树的先序遍历和中序遍历。目标是从中构造一个二叉树。
示例:
考虑下面的树
树的先序遍历将是
[1,2,4,3,5,6]
树的中序遍历将是
[4,2,1,5,3,6]
将给定先序和中序数组,我们必须再次从中序和先序构造树。以下是策略
-
我们将使用三个索引,分别是数组的起始、结束和当前索引
-
先序中的起始索引将是根。
-
我们将在中序数组中找到一个索引,其值与先序数组的起始索引处的值匹配。我们将这个索引称为 rootIndex。
-
中序数组中 rootIndex 左侧的所有值将位于左子树中
-
中序数组中 rootIndex 右侧的所有值将位于右子树中
-
然后我们可以用相同的策略递归左子树,再递归右子树。
例如
-
先序遍历的第一个索引是根,其值为1
-
值1在中序遍历的第 2个索引上。因此 rootIndex 是2
-
中序遍历中 rootIndex 左侧的部分是[4,2],这部分属于左子树
-
中序遍历中 rootIndex 右侧的部分是[5,3,6],这部分属于右子树
-
我们可以先递归左子树,然后递归右子树
程序
下面是相同程序的代码
package main
import (
"fmt"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func buildTree(preorder []int, inorder []int) *TreeNode {
lenOfTree := len(preorder)
current := 0
newRoot := buildTreeUtil(preorder, inorder, ¤t, 0, lenOfTree-1)
return newRoot
}
func buildTreeUtil(preorder []int, inorder []int, current *int, low, high int) *TreeNode {
if low > high {
return nil
}
if low == high {
rootNode := &TreeNode{Val: preorder[*current]}
(*current)++
return rootNode
}
rootNode := &TreeNode{Val: preorder[*current]}
rootValue := preorder[*current]
(*current)++
var rootIndex int
for i := low; i <= high; i++ {
if inorder[i] == rootValue {
rootIndex = i
}
}
rootNode.Left = buildTreeUtil(preorder, inorder, current, low, rootIndex-1)
rootNode.Right = buildTreeUtil(preorder, inorder, current, rootIndex+1, high)
return rootNode
}
func main() {
inorder := []int{4, 2, 1, 5, 3, 6}
preorder := []int{1, 2, 4, 3, 5, 6}
root := buildTree(preorder, inorder)
fmt.Printf("root: %d\n", root.Val)
fmt.Printf("root.Left: %d\n", root.Left.Val)
fmt.Printf("root.Left.Left: %d\n", root.Left.Left.Val)
fmt.Printf("root.Right: %d\n", root.Right.Val)
fmt.Printf("root.Right.Left: %d\n", root.Right.Left.Val)
fmt.Printf("root.Right.Right: %d\n", root.Right.Right.Val)
}
输出
root: 1
root.Left: 2
root.Left.Left: 4
root.Right: 3
root.Right.Left: 5
root.Right.Right: 6
注意: 查看我们的 Golang 高级教程。本系列的教程内容详尽,我们尽力涵盖所有概念和示例。本教程适合那些希望获得专业知识和深入理解 Golang 的读者 - Golang 高级教程
如果你有兴趣了解所有设计模式如何在 Golang 中实现。如果是的话,这篇文章就是为你准备的 - 所有设计模式 Golang
联系我们
嗨,你好,
我们期待收到你的消息。请随时通过下面的表单与我们联系,我们会尽快回复你。
Go(Golang)中的 float32 与 float64 之间的转换
目录
-
概述
-
float32 转 float64
-
float64 转 float32
概述
Golang 需要显式转换才能在两种类型之间转换。float32 和 float64 数据类型之间的转换需要显式类型转换。下面是语法。
{destination_type}(some_value)
这将 some_value 转换为 destination_type。
float32 转 float64
var a float32 = 12
var b float64 = float64(a)
或
b := float64(a)
下面是相应的工作程序
package main
import "fmt"
func main() {
var a float32 = 12.0
var b float64 = float64(a)
fmt.Printf("Underlying Type of b: %T\n", b)
b2 := float64(a)
fmt.Printf("Underlying Type of b2: %T\n", b2)
}
输出
Underlying Type of b: float64
Underlying Type of b2: float64
float64 转 float32
var a float64 = 12
var b float32 = float32(a)
或
b := float32(a)
下面是相应的工作程序。
package main
import "fmt"
func main() {
var a float64 = 12.0
var b float32 = float32(a)
fmt.Printf("Underlying Type of b: %T\n", b)
b2 := float32(a)
fmt.Printf("Underlying Type of b2: %T\n", b2)
}
如果我们直接将 float64 值赋给 float32,或反之,且没有明确转换,将会引发编译错误。
cannot use a (type float64) as type float32 in assignment
同时,查看我们的 Golang 进阶教程系列 – Golang 进阶教程
在 Go (Golang)中,映射与 JSON 之间的转换。
目录
-
概述
-
映射到 JSON
-
JSON 到映射
概述
encoding/json包提供了用于转换到 JSON 和从 JSON 转换的工具。可以使用相同的工具将 Golang 映射转换为 JSON 字符串,反之亦然。但需要注意的是,映射允许键的整数值,而 JSON 不允许键的整数值。JSON 仅允许键的字符串值。因此,当将具有整数键值的映射转换为 JSON 时,键将具有字符串值。
映射到 JSON
让我们来看一个将映射转换为 JSON 的程序。
package main
import (
"encoding/json"
"fmt"
)
func main() {
a := make(map[int]string)
a[1] = "John"
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
}
输出
{"1":"John"}
在上面的代码中,我们使用json.Marshal函数将映射转换为 JSON。该映射的键对应一个整数值。
a := make(map[int]string)
在转换后,结果 JSON 作为键的字符串值。
{"1":"John"}
让我们再看一个例子,在这个例子中,我们将映射转换为JSON,其中映射的值是一个结构体。以下是相关代码。
package main
import (
"encoding/json"
"fmt"
)
type employee struct {
Name string
}
func main() {
a := make(map[string]employee)
a["1"] = employee{Name: "John"}
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
}
输出
{"1":{"Name":"John"}}
JSON 到映射
让我们尝试将 JSON 转换为映射。我们将把上面示例中得到的 JSON 结果转换回映射。
json.Unmarshal函数可用于将 JSON 转换回映射。
第一种情况:
package main
import (
"encoding/json"
"fmt"
)
func main() {
a := make(map[int]string)
a[1] = "John"
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
var b map[int]string
json.Unmarshal(j, &b)
fmt.Println(b)
}
输出
{"1":"John"}
map[1:John]
第二种情况
package main
import (
"encoding/json"
"fmt"
)
type employee struct {
Name string
}
func main() {
a := make(map[string]employee)
a["1"] = employee{Name: "John"}
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
var b map[int]employee
json.Unmarshal(j, &b)
fmt.Println(b)
}
输出
{"1":{"Name":"John"}}
map[1:{John}]
Go(Golang)中结构体与 JSON 之间的转换。
目录
-
概述
-
结构体转 JSON
-
JSON 转结构体
概述
encoding/json 包提供了可以用于 JSON 转换的工具。相同的工具可以用于将 Go 结构体转换为 JSON 字符串及其反向转换。使用的两个函数是。
-
Marshal - 将结构体转换为 JSON 字符串。
-
Unmarshal - 将 JSON 字符串转换回结构体。
在我们查看如何将结构体转换为 JSON 及其反向转换之前,我们需要了解 Go 结构体的两件事:
-
只有结构体的导出字段对外部库可见。因此,在转换后的 JSON 字符串中仅会存在结构体的导出字段。还要注意,在 Go 中,结构体的大写字段是导出的。
-
结构体字段具有一个元部分,其中包含有关该字段的附加信息。这些元字段在将结构体转换为 JSON 及其反向转换时使用。此外,请注意这些结构体元字段是可选的。假设我们有以下结构体。
type employee struct {
Name string `json:"name"`
Age int `json:"age"`
}
注意与每个字段关联的元标签,这些字段的名称为 ‘json’。在将结构体转换为 JSON 及其反向转换时使用这些元字段。
因此,上述结构体转换为 JSON 后将如下所示。
{
"name" : "John",
"age" : 21
}
那么上述 JSON 字符串中的 name 键将映射到 employee 结构体的 Name 字段,而 JSON 字符串中的 age 键将映射到结构体的 Age 字段。此外,在将上述 JSON 字符串转换为结构体时,JSON 中 name 字段的值将传递给结构体的 Name 字段,而 JSON 中 age 字段的值将传递给结构体的 Age 字段。
作为另一个示例,假设我们有以下结构体。
type employee struct {
Name string `json:"n"`
Age int `json:"ag"`
}
然后在转换为 JSON 后,JSON 的 ‘n’ 键将映射到结构体的 Name 字段,而 JSON 的 ‘ag’ 键将映射到结构体的 Age 字段。因此,它将生成如下 JSON。
{
"n" : "John",
"age" : 21
}
此外,在将上述 JSON 字符串转换为结构体时,JSON 字符串中的 ‘n’ 字段的值将传递给结构体的 Name 字段,而 JSON 中 ‘a’ 字段的值将传递给结构体的 Age 字段。
如果结构体不包含任何元标签,则结果 JSON 中的键名将与结构体字段的名称相同,反之亦然。例如,如果我们有以下结构体。
type employee struct {
Name string
Age int
}
注意,字段没有 JSON 元数据标签。因此,转换为 JSON 后将如下所示。
{
"Name" : "John",
"Age" : 21
}
结构体转 JSON
json.Marshal 函数可用于将结构体转换为 JSON。让我们来看一个从结构体转换为 JSON 的示例。为说明以上所有要点,我们创建了两个结构体。
-
employee1 结构体 - 它具有元标签。
-
employee2结构体 - 它没有元标签。
此外,两个结构体中的 salary 字段均为未导出。
package main
import (
"encoding/json"
"fmt"
"log"
)
type employee1 struct {
Name string `json:"n"`
Age int `json:"a"`
salary int `json:"s"`
}
type employee2 struct {
Name string
Age int
salary int
}
func main() {
e1 := employee1{
Name: "John",
Age: 21,
salary: 1000,
}
j, err := json.Marshal(e1)
if err != nil {
log.Fatalf("Error occured during marshaling. Error: %s", err.Error())
}
fmt.Printf("employee1 JSON: %s\n", string(j))
e2 := employee2{
Name: "John",
Age: 21,
salary: 1000,
}
j, err = json.Marshal(e2)
if err != nil {
log.Fatalf("Error occured during marshaling. Error: %s", err.Error())
}
fmt.Printf("\nemployee2 JSON: %s\n", string(j))
}
输出
employee1 JSON: {"n":"John","a":21}
employee2 JSON: {"Name":"John","Age":21}
请注意,我们使用json.Marshal函数将结构体转换为 JSON。
对于employee1结构体到 JSON 的转换,输出为
{"n":"John","a":21}
这是因为
-
salary字段在输出中不存在,因为它未导出,即该字段未大写。
-
由于与employee1结构体关联的 JSON 标签,‘Name’字段映射到 JSON 的‘n’字段,而‘Age’字段映射到 JSON 的‘a’字段。
对于employee2结构体到 JSON 的转换,输出为
{"Name":"John","Age":21}
这是因为
-
salary字段在输出中不存在,因为它未导出,即该字段未大写。
-
由于employee2结构体没有关联任何 JSON 标签,employee1结构体的‘Name’字段映射到 JSON 的‘Name’字段,而‘Age’字段映射到 JSON 的‘Age’字段。
JSON 到结构体
json.Unmarshal函数可用于将 JSON 转换为结构体。我们之前讨论的规则同样适用于从 JSON 转换为结构体。让我们来看一个例子。
package main
import (
"encoding/json"
"fmt"
"log"
)
type employee1 struct {
Name string `json:"n"`
Age int `json:"a"`
salary int `json:"s"`
}
type employee2 struct {
Name string
Age int
salary int
}
func main() {
e1Json := `{"n":"John","a":21}`
var e1Converted employee1
err := json.Unmarshal([]byte(e1Json), &e1Converted)
if err != nil {
log.Fatalf("Error occured during unmarshaling. Error: %s", err.Error())
}
fmt.Printf("employee1 Struct: %#v\n", e1Converted)
e2Json := `{"Name":"John","Age":21}`
var e2Converted employee2
err = json.Unmarshal([]byte(e2Json), &e2Converted)
if err != nil {
log.Fatalf("Error occured during unmarshaling. Error: %s", err.Error())
}
fmt.Printf("\nemployee2 Struct: %#v\n", e2Converted)
}
输出
employee1 Struct: main.employee1{Name:"John", Age:21, salary:0}
employee2 Struct: main.employee2{Name:"John", Age:21, salary:0}
此示例使用了第一个示例的输出 JSON 字符串。在这里,我们使用json.Unmarshal函数将 JSON 字符串转换为结构体。首先需要注意的是,我们需要将结构体的地址传递给json.Unmarshal函数,如下所示。
err = json.Unmarshal(j, &e1Converted)
第一个参数是 JSON 字节,第二个是结构体的地址。
解组
{"n":"John","a":21}
输出到employee1结构体。
main.employee1{Name:"John", Age:21, salary:0}
解组
{"Name":"John","Age":21}
输出到employee2结构体。
main.employee2{Name:"John", Age:21, salary:0}
如果你尝试解组
{"n":"John","a":21}
into employee2 struct then the output will be
main.employee2{Name:"", Age:0, salary:0}
由于employee2结构体中没有元标签,且employee2结构体中的键名与 JSON 中的键名不同,因此不会进行解组。因此将创建一个空的employee2结构体,结构体中的每个字段都将初始化为其类型的默认零值。
如果 JSON 字符串包含salary字段,那么 JSON 字符串中的salary字段的值将不会反映在结构体的salary字段中,因为salary字段在结构体中未导出。请参见此示例。
package main
import (
"encoding/json"
"fmt"
"log"
)
type employee1 struct {
Name string `json:"n"`
Age int `json:"a"`
salary int `json:"s"`
}
func main() {
e1Json := `{"n":"John","a":21,"salary":1000}`
var e1Converted employee1
err := json.Unmarshal([]byte(e1Json), &e1Converted)
if err != nil {
log.Fatalf("Error occured during unmarshaling. Error: %s", err.Error())
}
fmt.Printf("employee1 Struct: %#v\n", e1Converted)
}
输出
employee1 Struct: main.employee1{Name:"John", Age:21, salary:0}
尽管 JSON 字符串中的salary字段值为 1000,但在转换为结构体后,结构体中的salary字段为 0。
在 Go (Golang) 中将 JSON 转换为 map。
目录
-
概述**
-
示例
概述
encoding/json 包提供的工具可以用于在 JSON 之间进行转换。相同的工具可以用于将 Golang map 转换为 JSON 字符串,反之亦然。
示例
json.Unmarshal 函数可以用于将 JSON 转换为 map。
可能有两种情况。
- 如果你知道 JSON 的格式,那么请按相同格式初始化 map。例如,当我们知道 JSON 中的值部分为字符串类型时,我们可以按以下格式初始化 map。
map[string]string
- 如果 JSON 的格式未知,则需要按照以下格式初始化相应的 map。值部分需要是一个空接口。
map[string]interface{}
让我们看看一些示例。在第一个示例中,我们有以下 JSON 字符串。
{"1":"John"}
假设 JSON 的格式是已知的。以下是程序。
package main
import (
"encoding/json"
"fmt"
)
func main() {
j := `{"1":"John"}`
var b map[string]string
json.Unmarshal([]byte(j), &b)
fmt.Println(b)
}
输出
map[1:John]
在第二个示例中,我们有以下 JSON 字符串。
{"1":{"Name":"John"}}
我们正在将这个 JSON 字符串解析成下面的 map 类型。
map[int]employee
其中 employee 是一个结构体。
type employee struct {
Name string
}
这是代码。
package main
import (
"encoding/json"
"fmt"
)
type employee struct {
Name string
}
func main() {
j := `{"1":{"Name":"John"}}`
var b map[int]employee
json.Unmarshal([]byte(j), &b)
fmt.Println(b)
}
输出
map[1:{John}]
让我们再看看一种情况,即 JSON 的格式未知的例子。
package main
import (
"encoding/json"
"fmt"
)
func main() {
j := `{"1":"John"}`
var b map[string]interface{}
json.Unmarshal([]byte(j), &b)
fmt.Println(b["1"])
}
输出
John
在 Go 中将映射转换为 JSON
目录
-
概述
-
示例
概述
encoding/json包提供了可以用于转换为 JSON 和从 JSON 转换的工具。相同的工具可以用来将 Golang 映射转换为 JSON 字符串,反之亦然。需要注意的一个重要点是,映射允许整数作为键,而 JSON 不允许整数作为键。JSON 只允许字符串作为键。因此,具有整数值作为键的映射在转换为 JSON 时,键将是字符串值。
示例
让我们看看将映射转换为 JSON 的程序
package main
import (
"encoding/json"
"fmt"
)
func main() {
a := make(map[int]string)
a[1] = "John"
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
}
输出
{"1":"John"}
在上面的代码中,我们使用json.Marshal函数将映射转换为 JSON。该映射的键是整数值。
a := make(map[int]string)
转换后,结果 JSON 的键为字符串值
{"1":"John"}
让我们再看一个示例,我们将一个映射转换为JSON,其中映射的值是一个结构体。以下是相应的代码
package main
import (
"encoding/json"
"fmt"
)
type employee struct {
Name string
}
func main() {
a := make(map[string]employee)
a["1"] = employee{Name: "John"}
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
}
输出
{"1":{"Name":"John"}}
将已排序的链表转换为平衡的二叉搜索树
目录
-
概述
-
程序
概述
目标是将已排序的链表转换为平衡的二叉搜索树。平衡的二叉搜索树是指每个节点的两个子树深度差不超过 1 的二叉搜索树。
假设我们有以下已排序的链表
-2->-1->0->1->2
然后它应该生成一个平衡的二叉搜索树。
程序
以下是相应程序
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
type SingleList struct {
Len int
Head *ListNode
}
func (s *SingleList) AddFront(num int) {
ele := &ListNode{
Val: num,
}
if s.Head == nil {
s.Head = ele
} else {
ele.Next = s.Head
s.Head = ele
}
s.Len++
}
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func sortedListToBST(head *ListNode) *TreeNode {
len := lenOfList(head)
return sortedListToBSTUtil(&head, len)
}
func sortedListToBSTUtil(head **ListNode, n int) *TreeNode {
if *head == nil {
return nil
}
if n <= 0 {
return nil
}
left := sortedListToBSTUtil(head, n/2)
root := &TreeNode{Val: (*head).Val}
*head = (*head).Next
root.Left = left
root.Right = sortedListToBSTUtil(head, n-n/2-1)
return root
}
func lenOfList(head *ListNode) int {
length := 0
for head != nil {
length++
head = head.Next
}
return length
}
func main() {
singleList := &SingleList{}
fmt.Printf("AddFront: 2\n")
singleList.AddFront(2)
fmt.Printf("AddFront: 1\n")
singleList.AddFront(1)
fmt.Printf("AddFront: 0\n")
singleList.AddFront(0)
fmt.Printf("AddFront: -1\n")
singleList.AddFront(-1)
fmt.Printf("AddFront: -2\n")
singleList.AddFront(-2)
fmt.Println()
root := sortedListToBST(singleList.Head)
fmt.Printf("root: %d\n", root.Val)
fmt.Printf("root.Left: %d\n", root.Left.Val)
fmt.Printf("root.Left.Left: %d\n", root.Left.Left.Val)
fmt.Printf("root.Right: %d\n", root.Right.Val)
fmt.Printf("root.Right.Left: %d\n", root.Right.Left.Val)
}
输出
AddFront: 2
AddFront: 1
AddFront: 0
AddFront: -1
AddFront: -2
root: 0
root.Left: -1
root.Left.Left: -2
root.Right: 2
root.Right.Left: 1
注意: 查看我们的 Golang 高级教程。本系列教程详尽,我们试图用示例覆盖所有概念。本教程适合那些希望获得专业知识并深入理解 Golang 的人 - Golang 高级教程
如果你对如何在 Golang 中实现所有设计模式感兴趣,这篇文章就是为你准备的 - 所有设计模式 Golang
将整型数组或数字转换为 Go(Golang)中的字符串
目录
-
概述
-
程序
概述
在本教程中,我们将学习如何在 Go 中将整型或数字数组转换为字符串。
下面是相应的程序。
程序
这里是相应的程序。
package main
import (
"fmt"
"strconv"
)
func main() {
sample := []int{2, 1, 3}
output := ""
for _, v := range sample {
temp := strconv.Itoa(v)
output = output + temp
}
fmt.Println(output)
}
输出
213
注意: 查看我们的 Golang 高级教程。本系列教程内容详尽,我们努力覆盖所有概念并提供示例。本教程适合希望获得专业知识和对 Golang 有深入理解的学习者 – Golang 高级教程
如果你有兴趣了解所有设计模式如何在 Golang 中实现,那么这篇文章适合你 –
注意: 查看我们的系统设计教程系列 系统设计问题*
在 Go (Golang) 中将数组/切片转换为 JSON
目录
-
概述
-
示例
概述
encoding/json 包提供了 Marshal 函数,可用于将 golang 数组或切片转换为 JSON 字符串,反之亦然。
让我们看看一个例子
示例
package main
import (
"encoding/json"
"fmt"
)
func main() {
a := make([]string, 2)
a[0] = "John"
a[1] = "Sam"
j, err := json.Marshal(a)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
}
输出
["John","Sam"]
```*
<!--yml
分类:未分类
日期:2024-10-13 06:52:30
-->
# 将 IOTA 或枚举转换为 Go 语言中的字符串
> 来源:[`golangbyexample.com/convert-an-iota-or-enum-to-a-string-in-go-golang/`](https://golangbyexample.com/convert-an-iota-or-enum-to-a-string-in-go-golang/)
目录
+ 概述
+ 示例
# 概述
在 Golang 中,可以通过使用 IOTA 创建枚举。请参考这篇文章以了解更多关于 IOTA 的信息。
> [Go 语言中的 IOTA](https://golangbyexample.com/iota-in-golang/)
[`golangbyexample.com/iota-in-golang/embed/#?secret=0FEJ5OZNxf#?secret=4y3pVxudgT`](https://golangbyexample.com/iota-in-golang/embed/#?secret=0FEJ5OZNxf#?secret=4y3pVxudgT)
在这篇文章中,我们将看到如何将 IOTA 或枚举转换为字符串值。默认情况下,当打印 IOTA 或枚举值时,它将打印其整数部分。请看这个例子。稍后我们将看到如何定义自定义的**toString**方法以打印 IOTA 或枚举的字符串值。
# 示例
```go
package main
import "fmt"
type Size uint8
const (
small Size = iota
medium
large
extraLarge
)
func main() {
fmt.Println(small)
fmt.Println(medium)
fmt.Println(large)
fmt.Println(extraLarge)
}
输出
0
1
2
3
我们还可以在 Size 类型上定义一个toString方法,以打印枚举的确切值。请看下面的程序。
package main
import "fmt"
type Size int
const (
small = Size(iota)
medium
large
extraLarge
)
func main() {
var m Size = 1
m.toString()
}
func (s Size) toString() {
switch s {
case small:
fmt.Println("Small")
case medium:
fmt.Println("Medium")
case large:
fmt.Println("Large")
case extraLarge:
fmt.Println("Extra Large")
default:
fmt.Println("Invalid Size entry")
}
}
输出
medium
现在我们将为Size类型定义一个toString方法。它可以用来打印 Size 类型常量的字符串值。
在 Go(Golang)中将浮点数转换为整数
目录
-
概述
-
float64 转 int
-
float32 转 int
概述
Golang 需要明确转换才能在不同类型之间进行转换。浮点数据类型可以通过显式类型转换直接转换为浮点数据类型。以下是其语法。
{destination_type}(some_value)
这将some_value转换为目标类型。
float64 转 int
var a float64 = 12
var b int = int(a)
或
b := int(a)
以下是相应的程序
package main
import "fmt"
func main() {
var a float64 = 12
var b int = int(a)
fmt.Printf("Underlying Type of b: %T\n", b)
b2 := int(a)
fmt.Printf("Underlying Type of b2: %T\n", b2)
}
输出
Underlying Type of b: int
Underlying Type of b2: int
float32 转 int
var a float32 = 12
var b int = int(a)
或
b := int(a)
以下是相应的工作程序。
package main
import "fmt"
func main() {
var a float32 = 12
var b int = int(a)
fmt.Printf("Underlying Type of b: %T\n", b)
b2 := int(a)
fmt.Printf("Underlying Type of b2: %T\n", b2)
}
输出
Underlying Type of b: int
Underlying Type of b2: int
如果我们直接将浮点值赋给整数变量而没有明确转换,将会引发以下编译错误。
cannot use a (type float64) as type int in assignment
或
cannot use a (type float32) as type int in assignment
另外,请查看我们的 Golang 进阶教程系列 – Golang 进阶教程
在 Go 中将 int 转换为 float(Golang)
目录
-
概述
-
int 到 float64
-
int 到 float32
概述
Golang 需要显式转换才能从一种类型转换为另一种类型。int 数据类型可以通过显式类型转换直接转换为 float 数据类型。以下是语法。
{destination_type}(some_value)
这将some_value转换为destination_type。
int 到 float64
var a int = 12
var b float64 = float64(a)
或
b := float64(a)
以下是相同的程序
package main
import "fmt"
func main() {
var a int = 12
var b float32 = float64(a)
fmt.Printf("Underlying Type of b: %T\n", b)
b2 := float64(a)
fmt.Printf("Underlying Type of b2: %T\n", b2)
}
输出
Underlying Type of b: float64
Underlying Type of b2: float64
int 到 float32
var a int = 12
var b float32 = float32(a)
或
b := float32(a)
以下是相同的工作程序。
package main
import "fmt"
func main() {
var a int = 12
var b float32 = float32(a)
fmt.Printf("Underlying Type of b: %T\n", b)
b2 := float32(a)
fmt.Printf("Underlying Type of b2: %T\n", b2)
}
输出
Underlying Type of b: float32
Underlying Type of b2: float32
如果我们直接将一个 int 赋值给 float 变量而不进行转换,将会引发编译错误。
cannot use a (type int) as type float64 in assignment
另外,查看我们的 Golang 高级教程系列 – Golang 高级教程
将查询参数字符串转换为 Go(Golang)中的查询参数哈希
目录
-
概述
-
程序
概述
假设我们有以下查询参数字符串
a=b&x=y
我们希望输出的格式如下图所示
map[a:b x:y]
程序
下面是相应的程序
package main
import (
"fmt"
"strings"
)
func main() {
query_param_map := make(map[string]string)
input := "a=b&x=y"
input_split := strings.Split(input, "&")
for _, v := range input_split {
v_split := strings.Split(v, "=")
query_param_map[v_split[0]] = v_split[1]
}
fmt.Println(query_param_map)
}
输出
map[a:b x:y]
使用 Go (Golang) 将单链表转换为循环链表
目录
-
概述
-
程序
概述
使用 Golang 将单链表转换为循环链表
输入单链表:
"A" -> "B" -> "C" -> "D"
输出应该是一个循环链表:
"A" -> "B" -> "C" -> "D"
^ |
|____________________|
程序
本程序中有两个重要方法
-
ToCircular – 将单链表转换为循环链表
-
IsCircular – 检查一个链表是否为循环链表
package main
import "fmt"
type node struct {
data string
next *node
}
type singlyLinkedList struct {
len int
head *node
}
func initList() *singlyLinkedList {
return &singlyLinkedList{}
}
func (s *singlyLinkedList) AddFront(data string) {
node := &node{
data: data,
}
if s.head == nil {
s.head = node
} else {
node.next = s.head
s.head = node
}
s.len++
return
}
func (s *singlyLinkedList) Traverse() error {
if s.head == nil {
return fmt.Errorf("TraverseError: List is empty")
}
current := s.head
for current != nil {
fmt.Println(current.data)
current = current.next
}
return nil
}
//Function to convert singly linked list to circular linked list
func (s *singlyLinkedList) ToCircular() {
current := s.head
for current.next != nil {
current = current.next
}
current.next = s.head
}
func (s *singlyLinkedList) IsCircular() bool {
if s.head == nil {
return true
}
current := s.head.next
for current.next != nil && current != s.head {
current = current.next
}
return current == s.head
}
func main() {
singleList := initList()
fmt.Printf("AddFront: D\n")
singleList.AddFront("D")
fmt.Printf("AddFront: C\n")
singleList.AddFront("C")
fmt.Printf("AddFront: B\n")
singleList.AddFront("B")
fmt.Printf("AddFront: A\n")
singleList.AddFront("A")
err := singleList.Traverse()
if err != nil {
fmt.Println(err.Error())
}
fmt.Printf("Size: %d\n", singleList.len)
singleList.ToCircular()
isCircular := singleList.IsCircular()
fmt.Printf("Is Circular: %t\n", isCircular)
}
输出
AddFront: D
AddFront: C
AddFront: B
AddFront: A
A
B
C
D
Size: 4
Is Circular: true
使用 Go (Golang)将单链表转换为数组
目录
-
概述
-
程序
概述
使用 Golang 将单链表转换为数组
输入单链表:
"A" -> "B" -> "C" -> "D"
输出数组:
["A", "B", "C", "D"]
程序
package main
import "fmt"
type node struct {
data string
next *node
}
type singlyLinkedList struct {
len int
head *node
}
func initList() *singlyLinkedList {
return &singlyLinkedList{}
}
func (s *singlyLinkedList) AddFront(data string) {
node := &node{
data: data,
}
if s.head == nil {
s.head = node
} else {
node.next = s.head
s.head = node
}
s.len++
return
}
func (s *singlyLinkedList) Size() int {
return s.len
}
func (s *singlyLinkedList) Traverse() error {
if s.head == nil {
return fmt.Errorf("TraverseError: List is empty")
}
current := s.head
for current != nil {
fmt.Println(current.data)
current = current.next
}
return nil
}
//Function to convert singly linked list to an array
func (s *singlyLinkedList) ToArray() []string {
var myarr []string
current := s.head
for current.next != nil {
fmt.Printf("\nAdding Element to array: %s", current.data)
myarr = append(myarr, current.data)
current = current.next
}
fmt.Printf("\nAdding Element to array: %s", current.data)
myarr = append(myarr, current.data)
return myarr
}
func main() {
singleList := initList()
fmt.Printf("AddFront: D\n")
singleList.AddFront("D")
fmt.Printf("AddFront: C\n")
singleList.AddFront("C")
fmt.Printf("AddFront: B\n")
singleList.AddFront("B")
fmt.Printf("AddFront: A\n")
singleList.AddFront("A")
fmt.Printf("Size: %d\n", singleList.Size())
err := singleList.Traverse()
if err != nil {
fmt.Println(err.Error())
}
myarr := singleList.ToArray()
fmt.Println()
fmt.Println(myarr)
}
输出:
AddFront: D
AddFront: C
AddFront: B
AddFront: A
Size: 4
A
B
C
D
Adding Element to array: A
Adding Element to array: B
Adding Element to array: C
Adding Element to array: D
[A B C D]
在 Go (Golang) 中将字符串转换为小写
目录
-
概述
-
代码:
概述
在 GO 中,字符串是 UTF-8 编码的。GO 的 strings 包提供了一个 ToLower 方法,可以将所有 Unicode 字母转换为小写。该方法会返回字符串的副本,因为 GO 字符串是不可变的。
以下是该函数的签名
func ToLower(s string) string
我们来看看实际的代码
代码:
package main
import (
"fmt"
"strings"
)
func main() {
res := strings.ToLower("ABC")
fmt.Println(res)
res = strings.ToLower("ABC12$a")
fmt.Println(res)
}
输出:
abc
abc12$a
```*
<!--yml
类别:未分类
日期:2024-10-13 06:12:26
-->
# 在 Go(Golang)中将字符串转换为大写
> 来源:[`golangbyexample.com/golang-string-uppercase/`](https://golangbyexample.com/golang-string-uppercase/)
目录
+ 概述
+ 代码:
# **概述**
在 Go 语言中,字符串采用 UTF-8 编码。**strings** 包提供了一个 **ToUpper** 方法,可以将所有 Unicode 字母转换为大写。此方法将返回字符串的副本,因为 Go 中的字符串是不可变的。
以下是该函数的签名
让我们看看实际代码
# **代码:**
```go
package main
import (
"fmt"
"strings"
)
func main() {
res := strings.ToUpper("abc")
fmt.Println(res)
res = strings.ToUpper("abc12$")
fmt.Println(res)
}
输出:
[预览 1]*
在 Go 语言中转换不同时区的时间。
每个time.Time对象都有一个关联的location值。当你将任何time.Time对象的位置更改为其他位置时,该时间瞬间并不会改变。只有与该时间关联的location值会发生变化。与 time.Time 对象关联的location仅具有表示或显示逻辑。
In函数可用于更改与特定time.Time对象关联的location。每当在任何time.Time对象(例如 t)上调用In函数时,
-
创建了一个表示相同时间瞬间的t副本。
-
t的位置设置为传递给In函数的显示位置。
-
t被返回。
让我们看看下面的代码,它可以用来更改与特定时间相关的地点值。
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
loc, _ := time.LoadLocation("UTC")
fmt.Printf("UTC Time: %s\n", now.In(loc))
loc, _ = time.LoadLocation("Europe/Berlin")
fmt.Printf("Berlin Time: %s\n", now.In(loc))
loc, _ = time.LoadLocation("America/New_York")
fmt.Printf("New York Time: %s\n", now.In(loc))
loc, _ = time.LoadLocation("Asia/Dubai")
fmt.Printf("Dubai Time: %s\n", now.In(loc))
}
输出:
UTC Time: 2020-01-31 18:09:41.705858 +0000 UTC
Berlin Time: 2020-01-31 19:09:41.705858 +0100 CET
New York Time: 2020-01-31 13:09:41.705858 -0500 EST
Dubai Time: 2020-01-31 22:09:41.705858 +0400 +04
将 Unix 时间戳转换为 Go (Golang) 中的 time.Time
时间可以在 GO 中以 time.Time 和 Unix 时间戳 格式表示。Unix 时间戳,也称为纪元时间,是自 1970 年 1 月 1 日 00:00:00 UTC 以来经过的秒数。此时间也称为 Unix 纪元。下面的代码显示了转换过程。
-
time.Time 转 Unix 时间戳
-
Unix 时间戳转 time.Time
package main
import (
"fmt"
"time"
)
func main() {
tNow := time.Now()
//time.Time to Unix Timestamp
tUnix := tNow.Unix()
fmt.Printf("timeUnix %d\n", tUnix)
//Unix Timestamp to time.Time
timeT := time.Unix(tUnix, 0)
fmt.Printf("time.Time: %s\n", timeT)
}
输出:
timeUnix 1257894000
time.Time: 2009-11-10 23:00:00 +0000 UTC
Go 中的 CookieJar(Golang)
目录
-
概述
-
第一个示例
-
服务器
-
客户端
-
-
第二个示例
-
服务器
-
客户端
-
概述
Golang 中的 HTTP 客户端允许您指定一个CookieJar,用于管理在进行外部 HTTP 请求时的 cookies 存储和发送。如其名所示,可以将其视为一个包含 cookies 的罐子。
golang.org/pkg/net/http/#Client
以下是 net/http Client结构的结构。它包含一个名为Jar的实例变量,其类型为CookieJar接口。
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}
以下是CookieJar接口。
type CookieJar interface {
SetCookies(u *url.URL, cookies []*Cookie)
Cookies(u *url.URL) []*Cookie
}
net/http 提供了一个默认的 cookie jar 实现,符合上述CookieJar接口。我们在初始化 net/http 客户端时将使用它。
golang.org/pkg/net/http/cookiejar/#Jar
您还可以在初始化 net/http Client 结构时提供自定义 cookie jar,该结构实现了上述CookieJar接口。
HTTP 客户端以两种方式使用此 jar。
-
向此 Jar 中添加 cookies。您可以显式地将 cookies 添加到此 jar 中。如果服务器在响应头中发送 Set-Cookies 头,则这些 cookies 也将被添加到 jar 中。Set-Cookie 头中指定的所有 cookies 都将被添加。
-
在进行任何外部 HTTP 请求时,查询此 jar。它检查此 jar 以了解需要为特定域发送哪些 cookies。
让我们通过几个示例来说明 cookie jar。
在第一个示例中,客户端将在进行 HTTP 请求时添加一个 cookie。此 cookie 将在后续所有请求中发送到同一域。
在第二个示例中,我们将看到服务器发送Set-Cookie头,该 cookie 将在客户端设置。
第一个示例
在本示例中,我们将看到客户端如何在 cookie jar 中设置 cookie。首先,让我们创建一个服务器,以下是相关程序。
服务器
服务器监听 8080 端口,并有两个 API。
-
localhost:8080/doc
-
localhost:8080/doc/id
在这两个 API 中,我们打印接收到的请求头中的 cookies。
go.mod
module sample.com/server
go 1.16
server.go
package main
import (
"fmt"
"net/http"
)
func main() {
docHandler := http.HandlerFunc(docHandler)
http.Handle("/doc", docHandler)
docGetID := http.HandlerFunc(docGetID)
http.Handle("/doc/id", docGetID)
http.ListenAndServe(":8080", nil)
}
func docHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Cookie in First API Call")
for _, c := range r.Cookies() {
fmt.Println(c)
}
fmt.Println()
w.WriteHeader(200)
w.Write([]byte("Doc Get Successful"))
return
}
func docGetID(w http.ResponseWriter, r *http.Request) {
fmt.Println("Cookie in Second API Call")
for _, c := range r.Cookies() {
fmt.Println(c)
}
w.WriteHeader(200)
w.Write([]byte("Doc Get ID Successful"))
return
}
这是客户端代码。
客户端
go.mod
module sample.com/client
go 1.16
client.go
package main
import (
"fmt"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
)
var client http.Client
func init() {
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalf("Got error while creating cookie jar %s", err.Error())
}
client = http.Client{
Jar: jar,
}
}
func main() {
req, err := http.NewRequest("GET", "http://localhost:8080/doc", nil)
if err != nil {
log.Fatalf("Got error %s", err.Error())
}
cookie := &http.Cookie{
Name: "token",
Value: "some_token",
MaxAge: 300,
}
urlObj, _ := url.Parse("http://localhost:8080/")
client.Jar.SetCookies(urlObj, []*http.Cookie{cookie})
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Error occured. Error is: %s", err.Error())
}
defer resp.Body.Close()
fmt.Printf("StatusCode: %d\n", resp.StatusCode)
req, err = http.NewRequest("GET", "http://localhost:8080/doc/id", nil)
if err != nil {
log.Fatalf("Got error %s", err.Error())
}
resp, err = client.Do(req)
if err != nil {
log.Fatalf("Error occured. Error is: %s", err.Error())
}
defer resp.Body.Close()
fmt.Printf("StatusCode: %d\n", resp.StatusCode)
}
在上述客户端程序中,我们创建了一个带有 cookie jar 的 HTTP 客户端。
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalf("Got error while creating cookie jar %s", err.Error())
}
client = http.Client{
Jar: jar,
}
我们正在向 Cookie Jar 添加一个 cookie。
cookie := &http.Cookie{
Name: "token",
Value: "some_token",
MaxAge: 300,
}
urlObj, _ := url.Parse("http://localhost:8080/")
client.Jar.SetCookies(urlObj, []*http.Cookie{cookie})
现在运行服务器。
go run server.go
和客户端。
go run client.go
注意服务器端的输出。
Cookie in First API Call
token=some_token
Cookie in Second API Call
token=some_token
相同的 cookie 在客户端对服务器的第一次和第二次调用中自动发送。它是如何开箱即用的?这是因为CookieJar参与了这个过程。golang HTTP 客户端在进行 HTTP 调用之前检查 Cookie Jar。然后发送这个 cookie。
第二个示例
在第二个示例中,我们将看到服务器在 Set-Cookie 头中发送的 cookie 如何被保存到CookieJar中。然后它将在后续调用中发送。为了说明这一点,让我们也创建一个将发送 Set-Cookie 头的服务器。以下是服务器代码。
服务器
我们将创建一个服务器,创建两个 API。
-
localhost:8080/doc – 在这个 API 中,服务器将在响应中设置Set-Cookie头。我们将从 golang 程序发起这个调用。golang http 客户端将在其端保存这个 cookie。然后客户端将为对 localhost:8080 的任何其他请求发送相同的 cookie 回到服务器。
-
localhost:8080/doc/id – 这是一个示例 API,用于演示 golang http 客户端如何实际使用CookieJar在请求中发送在 Set-Cookie 头中接收到的相同 cookie。注意在第二个 API 的代码中,我们接收到的所有 cookies。
go.mod
module sample.com/server
go 1.16
server.go
package main
import (
"fmt"
"net/http"
)
func main() {
docHandler := http.HandlerFunc(docHandler)
http.Handle("/doc", docHandler)
docGetID := http.HandlerFunc(docGetID)
http.Handle("/doc/id", docGetID)
http.ListenAndServe(":8080", nil)
}
func docHandler(w http.ResponseWriter, r *http.Request) {
cookie := &http.Cookie{
Name: "id",
Value: "abcd",
MaxAge: 300,
}
http.SetCookie(w, cookie)
w.WriteHeader(200)
w.Write([]byte("Doc Get Successful"))
return
}
func docGetID(w http.ResponseWriter, r *http.Request) {
for _, c := range r.Cookies() {
fmt.Println(c)
}
w.WriteHeader(200)
w.Write([]byte("Doc Get ID Successful"))
return
}
我们在响应头的Set-Cookie中设置了以下 cookie。
cookie := &http.Cookie{
Name: "id",
Value: "abcd",
MaxAge: 300,
}
http.SetCookie(w, cookie)
这是客户端代码。
客户端
go.mod
module sample.com/client
go 1.16
client.go
package main
import (
"fmt"
"log"
"net/http"
"net/http/cookiejar"
)
var client http.Client
func init() {
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalf("Got error while creating cookie jar %s", err.Error())
}
client = http.Client{
Jar: jar,
}
}
func main() {
req, err := http.NewRequest("GET", "http://localhost:8080/doc", nil)
if err != nil {
log.Fatalf("Got error %s", err.Error())
}
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Error occured. Error is: %s", err.Error())
}
defer resp.Body.Close()
fmt.Printf("StatusCode: %d\n", resp.StatusCode)
req, err = http.NewRequest("GET", "http://localhost:8080/doc/id", nil)
if err != nil {
log.Fatalf("Got error %s", err.Error())
}
resp, err = client.Do(req)
if err != nil {
log.Fatalf("Error occured. Error is: %s", err.Error())
}
defer resp.Body.Close()
fmt.Printf("StatusCode: %d\n", resp.StatusCode)
}
在客户端,我们只是创建了一个指定了 CookieJar 的 HTTP 客户端。除此之外,我们只是进行了两个 API 调用。
现在首先运行服务器。它将在 8080 端口启动一个本地服务器。
go run server.go
现在运行客户端
go run client.go
注意服务器端第二个 API 的输出。可以看到,它是响应头中Set-Cookie返回的相同 cookie。
Printing the cookies in the Second API
id=abcd
这是它开箱即用的工作方式。
-
在第一次 API 调用中,golang http 客户端将Set-Cookie响应头中存在的所有 cookies 保存到CookieJar中。
-
在进行第二次 API 调用之前,它会检查CookieJar以确定需要发送给服务器的所有 cookies。然后,它会发送这些 cookies。
这就是关于 golang 中 cookie jar 的全部内容。希望你喜欢这个教程。另请查看我们的 Golang 高级教程系列 – Golang 高级教程