You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于database/sql.Scanner接口实现的两处技术疑问

关于database/sql.Scanner实现的疑问解答

代码示例

type Foo int

// Scan implements the database/sql.Scanner interface
func (f *Foo) Scan(value interface{}) error {
    switch value := value.(type) {
    case int64:
        *f = Foo(value)
    default:
        return fmt.Errorf("Invalid database type: %T %v", value, value)
    }
    return nil
}

问题1:Scan方法返回error类型,为何能返回fmt.Errorf(...)?

fmt.Errorf的返回值本身就属于error类型,完全符合Scan方法的返回要求。Go中的error是一个接口,只要实现了Error() string方法的类型都属于error类型,而fmt.Errorf返回的*errors.errorString结构体正好实现了这个方法,所以返回它是完全合法的。


问题2:关于*f = Foo(value)及rows.Scan()的相关疑问

  • *f = Foo(value)的作用:将数据库返回的int64值转换成Foo类型,然后赋值给调用该Scan方法的指针所指向的Foo变量。比如你声明了var foo Foo,调用rows.Scan(&foo)时,这个赋值操作会把数据库中的数值存入foo变量。
  • 传入rows.Scan()时会调用Foo.Scan()吗:会的。database/sql包在处理Scan参数时,会检查参数是否实现了Scanner接口(即是否拥有Scan(value interface{}) error方法),而*Foo正好实现了这个接口,所以会自动调用你编写的Scan方法。
  • 类型为int64时会执行Foo(value)转换吗:是的。Foo是基于int的自定义类型,int64到Foo的转换是合法的类型转换(只要数值在当前系统int的范围内),这一步会把int64类型的value转换为Foo类型,再赋值给*f。

内容的提问来源于stack exchange,提问作者clarkk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 00:42:58