如果资源是结构的成员,何时以及如何关闭资源

时间:2018-07-15 04:59:57

标签: go

这是使用defer的经典示例:

conn, err = amqp.Dial(rabbitMqConnectionString)
if err != nil {
    panic(err)
}
defer conn.Close()

在我的情况下,连接是struct的成员,我在不同的函数中使用此连接:

type MyServer {
  conn *Connection
}

func (s *MyServer) Run() {
  s.conn, err = amqp.Dial(rabbitMqConnectionString)
  if err != nil {
    panic(err)
  }
}

func (s *MyServer) DoSomethingWithConnection() {
  // ...do something with connection
}

在这种情况下,我无法在Run()方法中使用defer。但是在这种情况下,我需要在哪里以及如何关闭连接?

2 个答案:

答案 0 :(得分:2)

func (s *MyServer) Stop() {
    //Some teardown
   s.conn.Close()
}
func main(){
    var s *MyServer
    ...
    s.Run()
    defer s.Stop()
    s.DoSomethingWithConnection()
}

答案 1 :(得分:1)

您可以看到我streadway/amqp/integration_test.go,使用连接的函数负责将其关闭:

if c := integrationConnection(t, "txcommit"); c != nil {
    defer c.Close()
    ...
}

具有:

// Returns a connection to the AMQP if the AMQP_URL environment
// variable is set and a connection can be established.
func integrationConnection(t *testing.T, name string) *Connection {
    conn, err := Dial(integrationURLFromEnv())
    if err != nil {
        t.Errorf("dial integration server: %s", err)
        return nil
    }
    return loggedConnection(t, conn, name)
}

并且:

func loggedConnection(t *testing.T, conn *Connection, name string) *Connection {
    if name != "" {
        conn.conn = &logIO{t, name, conn.conn}
    }
    return conn
}