无法转换< nil>成类型...? [英] Could't convert <nil> into type ...?
问题描述
类型User 使用数据库/ sql查询数据库行到Go类型,我的代码片段如下: struct {
user_id int64
user_name字符串
user_mobile字符串
密码字符串
电子邮件接口{}
昵称字符串
字节字节
锁定bool
create_time字符串
注释字符串// 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)
$ / code>
MySQL:
正如你所看到的,一些字段的值 NULL
,所以我必须设置接口{ }
键入Go的User struct,它将 NULL 转换为
nil
。
--- FAIL:TestQueryUser(0.00s)
user_test.go:48:sql:列索引9上的扫描错误:不支持扫描,存储驱动程序。值类型< nil>到类型*字符串
有人有更好的方法吗?或者我必须更改MySQL字段并将其 DEFAULT''
strong>在sql包中有一些类型,例如 sql.NullString (可为空字符串在你的表中,并猜测 Nullint64 和 NullBool 和... usage :)),你应该在你的结构中使用它们。 长:有两种可用的界面,第一种是扫描仪,另一个是 当您调用 作为实现示例,我建议您在 sql中查看类型包。 另外还有一个在postgresql中使用JSONB / JSON类型的例子 驱动程序值通常 I tried to using database/sql for query database row into a Go type, my codes snippet following: MySQL:
As your see, some fields that has Somebody has a better way? or I must change the MySQL field and set its First the short answer : There is some types in sql package for example sql.NullString (for nullable string in your table and guess Nullint64 and NullBool and ... usage :) ) and you should use them in your struct. The long one : There is two interface for this available in go , first is Scanner and the other is Valuer for any special type in database, (for example,I use this mostly with JSONB in postgres) you need to create a type, and implement this two(or one of them) interface on that type. the scanner is used when you call for an example of implementation, I recommend to see the types in sql package. Also there is an example of a type to use with JSONB/JSON type in postgresql driver value is often 这篇关于无法转换< nil>成类型...?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
扫描
功能时,会使用扫描仪。来自数据库驱动程序的数据通常位于 [] byte
中,并且您负责处理它。另一个是在查询中将该值用作输入时使用的。如果你只需要读取数据,Scanner就足够了,反之亦然,如果你需要在查询中写入参数,估值器就足够了,结果正常就是一片字节(和一个错误)。
$ b
// GenericJSONField用于处理postgres
类型中的泛型json数据GenericJSONField map [string] interface {}
//扫描转换json字段进入我们的类型
func(v * GenericJSONField)Scan(src interface {})错误{
var b [] byte
switch src。(type){
case [] byte :
b = src。([] byte)
case string:
b = [] byte(src。(string))
case nil:
b = make([ ]字节,0)
默认值:
返回errors.New(不支持的类型)
}
返回json.Unmarshal(b,v)
}
//尝试获取数据库中的字符串切片表示形式
func(v GenericJSONField)Value()(driver.Value,error){
return json.Marshal (v)
}
[]字节
但是 string
和 ni l
是可以接受的。所以这也可以处理无效字段。 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)
}
NULL
value, so I have to set interface{}
type into User struct of Go, which convert NULL
to 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
DEFAULT ' '
Scan
function. the data from the database driver, normally in []byte
is the input and you are responsible for handling it. the other one, is used when the value is used as input in query. the result "normally" is a slice of byte (and an error) if you need to only read data, Scanner is enough, and vice-versa, if you need to write parameter in query the Valuer is enough// 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
but string
and nil
is acceptable. so this could handle null-able fields too.