请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

db 并没有被初始化

直接贴代码

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的时候不使用:=来赋值。

请问老师,:= 这种赋值方式,是怎么判断是否要新创建一个变量的呢?

正在回答 回答被采纳积分+3

1回答

xiaomo 2019-03-28 14:55:10

同学你好, 这个就涉及到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在同一个作用域内,所以是同一个变量
}
1 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信