db 并没有被初始化
来源:3-6 编码实战:持久化元数据到文件表

海神名
2019-03-28
直接贴代码
package mysql
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"os"
)
var db *sql.DB
func init() {
var err error
db, err = sql.Open("mysql", "root:Haishen123@tcp(127.0.0.1:3306)/fileserver?charset=utf8")
// #####################
//db, err := sql.Open("mysql", "root:Haishen123@tcp(127.0.0.1:3306)/fileserver?charset=utf8")
// 这样写的话, db将会是init中创建的局部变量,而不是全局的db
// ####################
if err != nil {
fmt.Println(err.Error())
return
}
db.SetConnMaxLifetime(1000)
err = db.Ping()
if err != nil {
fmt.Println("Failed to connect to mysql, err: %s", err.Error())
os.Exit(1)
}
}
func DBConn() *sql.DB {
return db
}
如代码注释所示,如果按照注释的中的写法连接mysql的话,那么db将会是init函数中创建的局部变量,而定义在包全局的db任然是nil。所以我只能先创建一个err,在连接的sql的时候不使用:=来赋值。
请问老师,:= 这种赋值方式,是怎么判断是否要新创建一个变量的呢?
写回答
1回答
-
xiaomo
2019-03-28
同学你好, 这个就涉及到golang的变量作用域问题了.
对于 := 定义的变量,
1)如果不在同一个作用域里, 那么这个新的局部变量就会覆盖外层的同名变量, 相当于新定义了一个变量;
var db *sql.DB func init() { // 这种情况 db就是外层定义的db var err error db, err = sql.Open(...) // 没用到:= }
var db *sql.DB func init() { // 这种情况 db, err都是新定义的, 此db非外层的db db, err := sql.Open(...) }
2)如果在同一个作用域, 那么就会只定义没有定义过的变量, 比如:
var db *sql.DB func init() { // 这种情况 db非外层的db, 但err是(var err error)这个语句定义的err var err error db, err := sql.Open(...) // 两个err在同一个作用域内,所以是同一个变量 }
10
相似问题
return db 为nil
回答 1
slice初始化的疑问
回答 2