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

Golang 在接口指针上调用方法

Golang 在接口指针上调用方法

Go
蓝山帝景 2021-07-16 18:15:44
我正在使用Gorp进行数据库访问,Gorp 有一个标准DbMap类型,以及一个Transaction用于何时能够回滚的类型。这两种类型都实现了SqlExecutor接口。因此SqlExecutor,我针对接口进行编程,因此我可以根据需要使用事务而无需更改我的代码。然后我初始化一个 Gorp DbMaporTransaction并将其作为字段属性传入。问题是我需要一个指向 Gorp“对象”的指针,否则如果我使用 aTransaction如果 Gorp“对象”通过值而不是引用传递,我将如何能够回滚。然后我收到一条消息,例如r.Gorp.Get undefined (type *gorp.SqlExecutor has no field or method Get)当我尝试使用我的代码时。我如何调用这些方法?代码示例如下。package repositoriesimport (    "github.com/coopernurse/gorp")type Repository struct {    Gorp *gorp.SqlExecutor // <<<< Need pointer so I can rollback}func (r *Repository) GetById(i interface{}, key interface{}) interface{} {    obj, err := r.Gorp.Get(i, key)    if err != nil {        panic(err)    }    return obj}
查看完整描述

2 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

也许你对这个问题想得太多了,或者你可能仍然受到另一种语言的“引用调用”影响:

  1. gorp.SqlExecutor是一个接口,您永远不会使用指向接口值的指针。永远不能。(从技术上讲,这是不正确的,但是如果您确实需要一个指向接口的指针,那么您将已经掌握了足够的 Go 来理解为什么“从不”是一个非常好的建议。)

  2. 永远不要考虑“按引用调用”。Go 中没有这样的东西。将指针传递给函数不是“按引用调用”。把它抛在脑后。

我假设您没有尝试使用事务并对非指针接口代码进行回滚?

背景:在 Go 中,你传递一个指向某物的指针有两个原因:

1) 你想,因为你的结构真的 很大,你想避免复制,或者

2)你需要,因为被调用者想要修改原始的(这对于带有指针接收器的方法来说是典型的)。

现在接口值真的很小(只有两个词),因此传递指向接口值的指针的原因 1 不适用。原因 2 在大多数情况下不适用,因为将指针传递给接口值将允许您更改接口 本身,但大多数情况下您希望修改存储在其中的值接口值。存储在接口值中的这个值通常是一个指针值,它允许通过调用接口值上的方法来更改结构的值,该方法包装了指向该结构的指针。这听起来很复杂,但事实并非如此:新手 Go 程序员只是不使用指向接口的指针(因为这没有任何好处)并且有经验的 Go 程序员不使用指向接口的指针(因为它不会做太多好)除非他需要修改接口值,通常是在反射期间。


查看完整回答
反对 回复 2021-07-19
?
牛魔王的故事

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

  1. gorp.SqlExecutor是一个接口,您永远不会使用指向接口值的指针。永远不能。

  2. 如果这是您的目标,那么您就做错了。接口是一个包装器,是一个保证行为的契约。如果你的接口要求方法改变实现类型,那么实现类型应该是一个指针。指向接口本身的指针不会突然使实现类型可变。

  3. 你的结构应该是

type Repository struct {

    Gorp gorp.SqlExecutor 

}



func (r *Repository) GetById(i interface{}, key interface{}) interface{} {

    obj, err := r.Gorp.(gorp.SqlExecutor).Get(i, key)

    if err != nil {

        panic(err)

    }

    return obj

}


查看完整回答
反对 回复 2021-07-19
  • 2 回答
  • 0 关注
  • 322 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信