==问题描述==

如下代码,验证golang的xorm基本用法,

在init中加载了xorm的engine,并赋值给全局变量xe,结果在main中报空指针,提示xe为nil

package main

import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/go-xorm/xorm"
)

type PointInfo struct {
    Id         int64  `xorm:"pk autoincr"`
    ProductKey string `xorm:"product_key"`
    DeviceName string `xorm:"device_name"`
    PointId    string `xorm:"point_id"`
}

const (
    UserName = "root"
    PassWord = "RexelMySql998866"
    Host     = "47.116.50.192"
    Port     = "33306"
    Database = "pulse"
    Charset  = "utf8"
)

var xe *xorm.Engine

func init() {
    sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", UserName, PassWord, Host, Port, Database, Charset)

    // 1、创建数据库引擎
    xe, err := xorm.NewEngine("mysql", sqlStr)
    if err != nil {
        fmt.Println("数据库连接失败:", err)
        return
    }
    if xe == nil {
        fmt.Println("引擎初始化异常")
        return
    }

    // 2、创建或者同步表(名称为Stu)
    err = xe.Sync(new(PointInfo))
    if err != nil {
        fmt.Println("数据表同步失败:", err)
    }
}

func main() {
    id := insert()
    query(id)
    update(id)
    deleteOne(id)
}

func insert() (id int64) {
    pointInfo := new(PointInfo)
    pointInfo.ProductKey = "product1"
    pointInfo.DeviceName = "device1"
    pointInfo.PointId = "point1"

    affected, err := xe.Insert(pointInfo)
    if err != nil {
        return affected
    }
    fmt.Println(affected)
    return pointInfo.Id
}

func query(id int64) {
    pointInfo := PointInfo{Id: id}
    get, err := xe.Get(&pointInfo)
    if err != nil {
        return
    }
    fmt.Println(get)
}

func update(id int64) {
    pointInfo := new(PointInfo)
    pointInfo.ProductKey = "product2"
    pointInfo.DeviceName = "device2"
    pointInfo.PointId = "point2"
    affected, err := xe.Id(id).Update(pointInfo)
    if err != nil {
        return
    }
    fmt.Println(affected)
}

func deleteOne(id int64) {
    pointInfo := new(PointInfo)
    affected, err := xe.Id(id).Delete(pointInfo)
    if err != nil {
        return
    }
    fmt.Println(affected)
}

==原因分析==

xe变量在init中的是用:=生成的,所以xe是局部变量