请稍等 ...
×

采纳答案成功!

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

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

2回答

提问者 愫暮灬 2020-02-18 09:52:02

为什么要为每列赋值一个指针呢 遍历values赋值指针 和直接给一个空借口类型的值有什么不一样的呢

0 回复 有任何疑惑可以回复我~
  • xiaomo #1
    Rows.Scan方法只接收指针类型,不接收值类型(而且传值类型,函数内的赋值对函数外也不会产生任何效果呀)。可以参考参考官方文档,接收的入参类型包括:
    
    *string
    *[]byte
    *int, *int8, *int16, *int32, *int64
    *uint, *uint8, *uint16, *uint32, *uint64
    *bool
    *float32, *float64
    *interface{}
    *RawBytes
    *Rows (cursor value)
    any type implementing Scanner (see Scanner docs)
    回复 有任何疑惑可以回复我~ 2020-02-18 22:59:48
xiaomo 2020-02-18 09:08:06

同学你好,这种写法主要是为了实现在支持可变长参数的Scan函数中,给入参赋值的作用。

先来看看Scan函数的定义(https://www.godoc.org/database/sql#Row.Scan):

func (r *Row) Scan(dest ...interface{}) error

dest就是需要传入的可变长参数,如果入参是*interface{}类型,这样就可以不经过类型转换将数据拷贝赋值到入参中。

所以在实际的使用Scan过程中,我们可以这样使用(示例):

// ...
var name string
err := rows.Scan(&name)

// ...
var id int
var name string
err = rows.Scan(&id, &name)

// ...
scanArgs := make([]interface{}, len(columns)) // 临时存储每一行数据
for index, _ := range scanArgs { // 为每列元素初始化一个指针
    var tmp interface{}
    scanArgs[index] = &tmp
}
err := rows.Scan(scanArgs...)

// ...
scanArgs := make([]interface{}, len(columns))
values := make([]interface{}, len(columns))
for j := range values {
    scanArgs[j] = &values[j]
}
err := rows.Scan(scanArgs...)


0 回复 有任何疑惑可以回复我~
  • 提问者 愫暮灬 #1
    为什么要为每列赋值一个指针呢 遍历values赋值指针 和直接给一个空借口类型的值有什么不一样的呢
    回复 有任何疑惑可以回复我~ 2020-02-18 09:53:07
  • 拧壶冲 回复 提问者 愫暮灬 #2
    因为Scan接收一个指针类型,如果传values...到Scan里面会报错(在go1.14):
    "
    Scan error on column index 0, name "user_name": destination not a pointer
    exit status 1
    "
    回复 有任何疑惑可以回复我~ 2020-10-31 11:00:44
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信