猿问

Golang 在接口指针上调用方法

我正在使用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 repositories


import (

    "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

}


蓝山帝景
浏览 323回答 2
2回答

Qyouu

也许你对这个问题想得太多了,或者你可能仍然受到另一种语言的“引用调用”影响:gorp.SqlExecutor是一个接口,您永远不会使用指向接口值的指针。永远不能。(从技术上讲,这是不正确的,但是如果您确实需要一个指向接口的指针,那么您将已经掌握了足够的 Go 来理解为什么“从不”是一个非常好的建议。)永远不要考虑“按引用调用”。Go 中没有这样的东西。将指针传递给函数不是“按引用调用”。把它抛在脑后。我假设您没有尝试使用事务并对非指针接口代码进行回滚?背景:在 Go 中,你传递一个指向某物的指针有两个原因:1) 你想,因为你的结构真的&nbsp;很大,你想避免复制,或者2)你需要,因为被调用者想要修改原始的(这对于带有指针接收器的方法来说是典型的)。现在接口值真的很小(只有两个词),因此传递指向接口值的指针的原因 1 不适用。原因 2 在大多数情况下不适用,因为将指针传递给接口值将允许您更改接口&nbsp;值本身,但大多数情况下您希望修改存储在其中的值接口值。存储在接口值中的这个值通常是一个指针值,它允许通过调用接口值上的方法来更改结构的值,该方法包装了指向该结构的指针。这听起来很复杂,但事实并非如此:新手 Go 程序员只是不使用指向接口的指针(因为这没有任何好处)并且有经验的 Go 程序员不使用指向接口的指针(因为它不会做太多好)除非他需要修改接口值,通常是在反射期间。

牛魔王的故事

gorp.SqlExecutor是一个接口,您永远不会使用指向接口值的指针。永远不能。如果这是您的目标,那么您就做错了。接口是一个包装器,是一个保证行为的契约。如果你的接口要求方法改变实现类型,那么实现类型应该是一个指针。指向接口本身的指针不会突然使实现类型可变。你的结构应该是type Repository struct {&nbsp; &nbsp; Gorp gorp.SqlExecutor&nbsp;}func (r *Repository) GetById(i interface{}, key interface{}) interface{} {&nbsp; &nbsp; obj, err := r.Gorp.(gorp.SqlExecutor).Get(i, key)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; return obj}
随时随地看视频慕课网APP

相关分类

Go
我要回答