2024-08-23



package main
 
import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)
 
// 假设我们有一个API的请求结构体
type ApiRequest struct {
    Field1 string `json:"field1"`
    Field2 int    `json:"field2"`
}
 
// 假设我们有一个API的响应结构体
type ApiResponse struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}
 
func main() {
    // 创建API请求对象
    request := ApiRequest{
        Field1: "value1",
        Field2: 123,
    }
 
    // 序列化请求对象为JSON格式
    requestBody, err := json.Marshal(request)
    if err != nil {
        panic(err)
    }
 
    // 发起POST请求到第三方API
    resp, err := http.Post("https://api.example.com/endpoint", "application/json", bytes.NewBuffer(requestBody))
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
 
    // 读取响应体
    responseBody, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
 
    // 反序列化响应体到响应对象
    var response ApiResponse
    err = json.Unmarshal(responseBody, &response)
    if err != nil {
        panic(err)
    }
 
    // 输出API响应结果
    fmt.Printf("API Response: %+v\n", response)
}

这段代码展示了如何在Go中创建一个HTTP POST请求,发送JSON格式的数据到第三方API,并处理返回的JSON响应。代码中包含了错误处理,确保在发生任何错误时程序不会崩溃。

2024-08-23



package main
 
import (
    "fmt"
    "time"
)
 
func worker(id int, c chan int) {
    for n := range c {
        fmt.Printf("Worker %d received %d\n", id, n)
        time.Sleep(time.Second)
    }
}
 
func main() {
    const numWorkers = 3
    const numMessages = 5
 
    workers := make([]chan int, numWorkers)
 
    for i := range workers {
        workers[i] = make(chan int)
        go worker(i, workers[i])
    }
 
    for i := 0; i < numMessages; i++ {
        time.Sleep(time.Second)
        fmt.Printf("Master sending %d\n", i)
        for _, worker := range workers {
            worker <- i
        }
    }
 
    for _, worker := range workers {
        close(worker)
    }
 
    fmt.Scanln() // 阻塞主goroutine,防止程序立即退出
}

这段代码修复了原始代码中的问题,并提供了一个简单的Go程序示例,它创建了一个工作池,并向每个工作程序平均分配了任务。每个工作程序在自己的goroutine中运行,并且主goroutine会等待用户输入来防止程序立即退出。这个例子展示了Go语言中协程、通道和工作池模式的基本使用方法。

2024-08-23



# 安装并配置内网穿透工具 - 以 `frp` 为例
# 下载 frp 到你的 Windows 系统
frp_windows_amd64.zip (https://github.com/fatedier/frp/releases)
# 解压缩
 
# 配置 frps.ini
[common]
bind_port = 7000
 
# 启动 frps
./frps -c frps.ini
 
# 在你的 Linux 服务器上安装 frpc
# 下载 frp 到你的 Linux 服务器
frp_linux_amd64.zip (https://github.com/fatedier/frp/releases)
# 解压缩
 
# 配置 frpc.ini
[common]
server_addr = <你的 Windows IP>
server_port = 7000
 
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
 
[tunnel]
type = tcp
remote_port = 7001
local_ip = 127.0.0.1
local_port = 6333
 
# 启动 frpc
./frpc -c frpc.ini
 
# 在 GoLand 中配置 SSH 远程开发环境
# 打开 GoLand,选择 `File` > `Settings` > `Build, Execution, Deployment` > `Deployment`
# 点击 `+` 添加一个新的部署配置,选择 `SFTP`
# 填写你的服务器信息,用户名、主机、私钥等
# 在 `Mappings` 中配置本地目录与远程服务器目录的映射
# 保存配置并测试连接
 
# 配置端口转发,以便于 GoLand 可以通过内网穿透连接到你的开发环境
# 在 frpc.ini 中添加如下配置
[goland_debug_server]
type = tcp
local_ip = 127.0.0.1
local_port = 6333
remote_port = 6333
 
# 重启 frpc 使配置生效
 
# 在 GoLand 中配置远程解释器
# 选择 `File` > `Settings` > `Languages & Frameworks` > `Go` > `Go Modules (vgo)` 或 `Go SDK`
# 在 `SSH Interpreter` 中配置你的 SSH 连接信息,选择你刚才创建的部署配置
# 保存设置并重新启动 GoLand
 
# 现在你可以在 GoLand 中远程编辑、编译和调试 Linux 服务器上的 Go 代码了

这个例子展示了如何使用内网穿透工具 frp 将你的本地开发环境与远程的 Linux 服务器连接起来,并在 GoLand 中配置相关设置以实现远程开发和调试。这样可以在没有公网 IP 的情况下进行开发工作,特别适合家庭、办公室网络环境或在教育、个人项目中使用。

2024-08-23

go-callvis是一个用来可视化Go语言程序中函数调用关系的工具。以下是如何使用go-callvis的简单示例:

首先,你需要安装go-callvis:




go get -u github.com/ofabry/go-callvis

然后,你可以使用以下命令来生成一个HTML文件,其中包含了你的Go程序的函数调用关系图:




go-callvis -group pkg -min 1 your/package | fgrep -v "github.com/ofabry/go-callvis" > /tmp/callvis.html

这里的-group pkg选项表示按照包来分组显示调用关系,-min 1表示只显示最小深度为1的节点,your/package是你想要分析的Go语言包的路径。

最后,你可以在浏览器中打开生成的HTML文件来查看调用关系图:




open /tmp/callvis.html

这个命令会在你的默认浏览器中打开HTML文件,显示函数调用关系的可视化图。你可以通过拖动和缩放来浏览图表,也可以使用顶部的选择框来过滤特定的包或函数。

2024-08-23



package main
 
import (
    "fmt"
    "github.com/google/uuid"
)
 
func main() {
    // 使用Go标准库生成UUID
    u1 := uuid.New()
    fmt.Println("UUID Version 4:", u1)
 
    // 生成UUID并转化为字符串形式
    u2 := uuid.NewString()
    fmt.Println("UUID Version 4 (String):", u2)
}

这段代码演示了如何在Go语言中使用github.com/google/uuid库生成UUID。uuid.New()函数用于生成一个随机的UUID,而uuid.NewString()函数用于生成一个代表UUID的字符串。这是在Go中生成UUID的标准方法。

2024-08-23



package main
 
import "fmt"
 
// 定义一个简单的结构体
type Person struct {
    Name string
    Age  int
}
 
// 定义一个方法,接收一个Person类型的参数,返回一个表示个人信息的字符串
func (p Person) Introduce() string {
    return fmt.Sprintf("你好,我是%s,今年%d岁。", p.Name, p.Age)
}
 
func main() {
    // 创建一个Person实例
    person := Person{"小明", 25}
 
    // 调用方法并打印结果
    fmt.Println(person.Introduce())
}

这段代码定义了一个名为Person的结构体,并为其添加了一个名为Introduce的方法。在main函数中,我们创建了一个Person实例,并调用了Introduce方法,打印出了小明的个人介绍。这是Golang中的基本概念,对于学习者来说很容易理解和掌握。

2024-08-23

在Go语言中,如果你想在自己的项目中使用自己开发的包(库),你可以采用以下两种方式:

  1. 使用go get命令克隆你的包到GOPATH下。
  2. 如果你的包在Github或其他代码仓库,可以直接用go get命令克隆到GOPATH下,然后在go.mod中用相对路径引用。

以下是具体的操作步骤和示例:

方法一:使用go get命令克隆你的包到GOPATH下。

首先,你需要将你的包放在一个公开的代码仓库中,如GitHub、GitLab或者Gitee。然后在你的项目目录下运行以下命令:




go get github.com/your-username/your-package

然后在你的go.mod文件中添加以下内容:




require (
    github.com/your-username/your-package v0.0.0-20190101010101-abcdefabcdef
)

方法二:如果你的包在本地,可以用以下方式引用:

首先,在你的项目目录下运行go mod init your-project-name来初始化go.mod文件。

然后,在你的go.mod文件中添加以下内容:




require (
    your-local-package v0.0.0-20190101010101-abcdefabcdef
)
replace your-local-package => ../path-to-your-local-package

其中,your-local-package是你的本地包名,../path-to-your-local-package是你的本地包相对于你的项目目录的路径。

以上两种方法都可以让你在自己的Go项目中使用自己开发的包。在实际使用中,你可以根据你的具体情况选择合适的方法。

2024-08-23



package main
 
import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "gopkg.in/natefinch/lumberjack.v2"
)
 
// 配置初始化高性能Zap日志库
func InitZapLogger() (*zap.Logger, error) {
    // 根据需求配置日志的编码器,如果要使用JSON编码就使用NewJSONEncoder
    encoderConfig := zapcore.EncoderConfig{
        TimeKey:        "time",
        LevelKey:       "level",
        NameKey:        "logger",
        CallerKey:      "caller",
        MessageKey:     "msg",
        StacktraceKey:  "stacktrace",
        LineEnding:     zapcore.DefaultLineEnding,
        EncodeLevel:    zapcore.LowercaseLevelEncoder,  // 小写编码器
        EncodeTime:     zapcore.ISO8601TimeEncoder,     // ISO8601时间格式
        EncodeDuration: zapcore.SecondsDurationEncoder, // 持续时间秒数
    }
 
    // 设置日志级别
    atom := zap.NewAtomicLevelAt(zap.InfoLevel)
 
    // 配置日志的写入器,使用"lumberjack"进行日志轮转
    writeSyncer := zapcore.AddSync(&lumberjack.Logger{
        Filename:   "./logs/myapp.log", // 日志文件路径
        MaxSize:    100,               // 每个日志文件最大100MB
        MaxAge:     7,                 // 最多保留7天的日志文件
        MaxBackups: 3,                 // 最多保留3个备份
        Compress:   true,              // 压缩日志文件
    })
 
    // 构建Zap日志库的核心
    core := zapcore.NewCore(
        zapcore.NewConsoleEncoder(encoderConfig), // 控制台编码器
        writeSyncer,                              // 写入器
        atom,                                     // 日志级别
    )
 
    // 构建Zap日志库
    logger := zap.New(core)
 
    return logger, nil
}
 
func main() {
    logger, err := InitZapLogger()
    if err != nil {
        panic(err)
    }
    defer logger.Sync()
 
    logger.Info("This is an info message")
    logger.Error("This is an error message")
}

这段代码首先定义了一个配置初始化高性能Zap日志库的函数InitZapLogger,它设置了日志的编码器、日志级别、写入器,并使用了"lumberjack"日志轮转库来管理日志文件。然后在main函数中,我们创建了一个日志库实例,并使用不同级别的日志方法进行了日志记录。这个例子展示了如何在Go语言中使用Zap日志库进行高效的日志记录。

2024-08-23

在开始学习一门新的编程语言时,通常需要了解该语言的特点、设计哲学以及如何开始编写代码。以下是一个简单的Golang程序,它展示了如何打印"Hello, World!"到控制台。




package main
 
import "fmt"
 
func main() {
    fmt.Println("Hello, World!")
}

在这个例子中,我们做了以下几点:

  1. 使用package main声明这是一个主程序,表示这是一个可以独立执行的程序。
  2. 使用import "fmt"导入了Go的标准格式化库,这是用来输出文本到控制台的。
  3. 定义了一个名为main的函数,这是Go程序的入口点。
  4. 使用fmt.Println()函数打印出字符串"Hello, World!"。

通过这个简单的例子,你可以开始你的Golang学习之旅。

2024-08-23



package main
 
import (
    "fmt"
)
 
// 定义一个简单的函数,接收两个整数参数并返回它们的和
func add(a, b int) int {
    return a + b
}
 
// 主函数,程序的入口点
func main() {
    // 调用add函数并打印结果
    sum := add(10, 20)
    fmt.Println("Sum is:", sum)
}

这段代码首先导入了Go语言的fmt包,这个包用于输入输出。然后定义了一个名为add的函数,它接受两个整型参数并返回它们的和。在main函数中,我们调用了add函数并打印出结果。这个例子展示了Go语言的基本语法和函数定义。