为了账号安全,请及时绑定邮箱和手机立即绑定

无法将 <nil> 转换为类型 ...?

无法将 <nil> 转换为类型 ...?

Go
蓝山帝景 2022-01-04 18:49:01
我尝试使用 database/sql 将数据库行查询为 Go 类型,我的代码片段如下:type User struct {    user_id     int64    user_name   string    user_mobile string    password    string    email       interface{}    nickname    string    level       byte    locked      bool    create_time string    comment     string  // convert <nil> to *string error }func TestQueryUser(t *testing.T) {    db := QueryUser(driverName, dataSourceName)    stmtResults, err := db.Prepare(queryAll)    defer stmtResults.Close()    var r *User = new(User)    arr := []interface{}{        &r.user_id, &r.user_name, &r.user_mobile, &r.password, &r.email,        &r.nickname, &r.level, &r.locked, &r.create_time, &r.comment,    }    err = stmtResults.QueryRow(username).Scan(arr...)    if err != nil {        t.Error(err.Error())    }    fmt.Println(r.email)}MySQL:如您所见,某些字段具有NULL值,因此我必须将interface{}类型设置为 Go 的 User 结构,然后将其转换NULL为nil.--- FAIL: TestQueryUser (0.00s)        user_test.go:48: sql: Scan error on column index 9: unsupported Scan, storing driver.Value type <nil> into type *string有人有更好的方法吗? 或者我必须更改 MySQL 字段并设置其 DEFAULT ' '
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

首先是简短的回答: sql 包中有一些类型,例如sql.NullString(用于表中的可为空字符串,并猜测Nullint64和NullBool和...用法:)),您应该在结构中使用它们。


长一个:有两种接口在走这个可用,首先是扫描仪,另一个是估值师对数据库的任何特殊类型,(例如,我用这主要与JSONB Postgres里),你需要创建一个类型,在该类型上实现这两个(或其中一个)接口。


调用Scan函数时会使用扫描仪。来自数据库驱动程序的数据,通常[]byte是输入,您负责处理它。另一个,当该值用作查询中的输入时使用。如果您只需要读取数据,则结果“通常”是一个字节(和一个错误),Scanner 就足够了,反之亦然,如果您需要在查询中写入参数 Valuer 就足够了


对于实现示例,我建议查看sql包中的类型。


还有一个在 postgresql 中与 JSONB/JSON 类型一起使用的类型示例


// GenericJSONField is used to handle generic json data in postgres

type GenericJSONField map[string]interface{}



// Scan convert the json field into our type

func (v *GenericJSONField) Scan(src interface{}) error {

    var b []byte

    switch src.(type) {

    case []byte:

        b = src.([]byte)

    case string:

        b = []byte(src.(string))

    case nil:

        b = make([]byte, 0)

    default:

        return errors.New("unsupported type")

    }


    return json.Unmarshal(b, v)

}


// Value try to get the string slice representation in database

func (v GenericJSONField) Value() (driver.Value, error) {

    return json.Marshal(v)

}

驱动值通常是[]byte但string并且nil是可以接受的。所以这也可以处理可为空的字段。


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 693 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号