2015-01-21 66 views
1
數據庫連接

通常我寫這樣的事情更好/更短的方式來關閉圍棋

rows := db.MyPgConn.QueryRows(`SELECT * FROM bla`) // or any other query 
for rows.Next() { // if there are result 
    // rows.Scan( 
    // do custom operation 
} 
rows.Close() // close recordset 

但這樣一來,有可能是我忘了寫rows.Close()就這樣code,可以使可用的數量連接/套接字耗盡,有沒有更好的方法來做到這一點?

+2

來自https://golang.org/doc/effective_go.html#defer「Go的延遲語句計劃了一個函數調用(延遲函數),在執行延遲的函數返回之前立即運行。有效的方法來處理諸如必須釋放的資源等情況,而不管函數返回的路徑。「 – Intermernet 2015-01-21 04:57:40

回答

1

正如Intermernet所述,defer語句是使close語句更接近聲明行var的最佳方式。我能想到的唯一方法可能會使這個更短或更簡單的方法是創建一個數據庫調用的包裝函數。

func performQuery(q string, op func(db.rows)) { 
    rows := db.MyPg.Conn.QueryRows(q) 
    // defer rows.Close() 
    op(rows) 
    rows.Close() 
} 

// then we could do: 
performQuery(`SELECT * FROM bla`,func(rows db.Rows) { 
    for rows.Next() { 
    // rows.Scan(  
    } 
}) 

然而,這會從參數(例如SELECT * FROM tableName WHERE id = $1進行查詢限制你

3

轉到引進defer正是爲了這個目的

rows := db.MyPgConn.QueryRows(`SELECT * FROM bla`) // or any other query 
defer rows.Close() 

for rows.Next() { // if there are result 
    // rows.Scan( 
    // do custom operation 
} 

從文檔:。

推遲對諸如Close之類的函數的調用tw優點。首先,它保證您永遠不會忘記關閉文件,如果稍後編輯函數以添加新的返回路徑,則很容易犯這個錯誤。其次,它意味着靠近開放位置,這比放置在函數末尾要清楚得多。