gpt4 book ai didi

go - 如何让 main() 等待直到 init() 在 golang 中完成?

转载 作者:行者123 更新时间:2023-12-01 22:38:51 27 4
gpt4 key购买 nike

当我使用以下代码运行我的 main.go 时,它可以正常工作并且客户端连接到 mongo 数据库。

package main

import (
"context"
"fmt"
"log"

"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

type Trainer struct {
Name string
Age int
City string
}

func main() {
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}

err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Successful connection")
}

但是,当我试图在 init() 之间分离代码逻辑时和 main() goroutines,我得到一个内存引用错误,这是正常的,因为 main 是在 init 实际上有一个 tcp 连接到 db 之前执行的。我试图将它们与一个 channel 连接,但它没有按预期工作。
package main

import (
"context"
"fmt"
"log"

"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

type Trainer struct {
Name string
Age int
City string
}

var client *mongo.Client
var c = make(chan *mongo.Client)

func init() {
// configures the connection options
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}

err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}

c <- client
}

func main() {
fmt.Println(<-c)
}

由于我对 golang 没有足够的经验,任何人都可以解释为什么我的解决方案不起作用以及如何解决它?如果可能的话,我希望将 init() 和 main() 分开。

最佳答案

您的代码存在三个问题:

1) init 和 main 函数不是 goroutine,它们在程序启动时顺序运行。所以使用无缓冲 channel 是没有意义的。

2) 变量 client 在 init 中使用 ':=' 操作符重新声明。

3) 我不建议在 init 中初始化客户端连接。如有必要,将代码放在辅助函数中并从 main 调用它。

涵盖 (1) 和 (2) 且不包括 (3) 的修复是:

package main

import (
"context"
"fmt"
"log"

"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

type Trainer struct {
Name string
Age int
City string
}

var client *mongo.Client
// We don't need a channel since init and main are not goroutines. Both
// are executed sequentially in the main thread.
// var c = make(chan *mongo.Client)


// It is not recommended to use init to setup database connections. It
// is definitely part of the program and belongs into main.
func init() {
// configures the connection options
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

// Don't redeclare client here. We have however to declare err.
var err error
// Note that we use assignment (=) and not declaration (:=).
client, err = mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}

err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
}

func main() {
// Use the global client variable instead reading from the channel.
fmt.Println(client)
}

关于go - 如何让 main() 等待直到 init() 在 golang 中完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58462185/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com