Golang add function to struct defined elsewhere

huangapple go评论87阅读模式
英文:

Golang add function to struct defined elsewhere

问题

我想在sql.Row结构体上创建一个函数,将一行数据扫描到我的结构体ErrorModel中。这是我的代码:

func (row *sql.Row) ScanErrorModel(mod *model.ErrorModel, err error) {
    err = row.Scan(&mod.MessageId, &mod.ServiceName, &mod.EventName,
        &mod.Hostname, &mod.Message, &mod.CriticalRate, &mod.Extra, &mod.Timestamp)
    return
}

func (dao *ErrorsDAO) Fetch(id string) (mod *model.ErrorModel, err error) {
    row := dao.DB.QueryRow("select * from errors where message_id=$1", id) 
    return row.ScanErrorModel()
}

但是我在这里遇到了一个编译错误:

row.ScanErrorModel undefined (type *sql.Row has no field or method ScanErrorModel)

在其他地方定义的结构体上添加函数是不可能的吗?还是我只是犯了语法错误?

英文:

I want to create a function on the sql.Row struct that scans a row into my struct ErrorModel. This is what I am doing:

func (row *sql.Row) ScanErrorModel(mod *model.ErrorModel, err error) {
    err = row.Scan(&mod.MessageId, &mod.ServiceName, &mod.EventName,
      &mod.Hostname, &mod.Message, &mod.CriticalRate, &mod.Extra, &mod.Timestamp)
    return
}

func (dao *ErrorsDAO) Fetch(id string) (mod *model.ErrorModel, err error) {
    row := dao.DB.QueryRow("select * from errors where message_id=$1", id) 
    return row.ScanErrorModel()
}

But I am getting a compiler error here:

row.ScanErrorModel undefined (type *sql.Row has no field or method ScanErrorModel)

Is it impossible to add a function onto a struct that is defined somewhere else like this? Or am I just making a syntax error?

答案1

得分: 9

你不能为非本地类型定义方法。根据规范

T所表示的类型被称为接收器基本类型;它不能是指针类型或接口类型,并且必须在与方法相同的包中声明

(强调添加。)

你可以创建自己的类型,并将导入的类型嵌入其中:

// 具有*sql.Row的所有方法。
type myRow struct {
    *sql.Row
}

func (row myRow) ScanErrorModel(mod *model.ErrorModel, err error) {
    err = row.Scan(&mod.MessageId, &mod.ServiceName, &mod.EventName,
      &mod.Hostname, &mod.Message, &mod.CriticalRate, &mod.Extra, &mod.Timestamp)
    return
}
英文:

You cannot define methods of non-local types. As per Spec:

>The type denoted by T is called the receiver base type; it must not be a pointer or interface type and it must be declared in the same package as the method.

(Emphasis added.)

What you can do is create your own type and embed the imported type into it:

// Has all methods of *sql.Row.
type myRow struct {
    *sql.Row
}

func (row myRow) ScanErrorModel(mod *model.ErrorModel, err error) {
    err = row.Scan(&mod.MessageId, &mod.ServiceName, &mod.EventName,
      &mod.Hostname, &mod.Message, &mod.CriticalRate, &mod.Extra, &mod.Timestamp)
    return
}

huangapple
  • 本文由 发表于 2015年6月12日 22:03:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/30805006.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定