我有以下代码,我想使用接口:
当前代码:
import (
"github.com/dorzheh/deployer/ui/dialog_ui"
. "github.com/dorzheh/go-dialog"
)
// all methods in https://github.com/dorzheh/deployer/blob/master/ui/dialog_ui/dialog_ui.go#L28
type Pb struct {
sleep time.Duration
step int
}
type DialogUi struct {
*Dialog //The source is https://github.com/dorzheh/go-dialog/blob/master/dialog.go#L34
Pb *Pb
}
我试图以这种方式实现接口:
import (
"testing"
// . "github.com/dorzheh/go-dialog"
//"github.com/dorzheh/deployer/ui/dialog_ui"
)
type PBifaceT interface {
Step() int
}
type TestDialogUiT struct {
Pb *PBifaceT
}
func TestUiValidateUser(t *testing.T) {
x := dialog_ui.TestDialogUiT{}
PbPb := ImplPBifaceT{}
x.Pb = PbPb
parentId := x.Pb.Step()
t.Logf(fmt.Sprintf("%v", parentId))
}
我做了playground。如您所见,它运行在以下错误中:
prog.go:23: cannot use PbPb (type ImplPBifaceT) as type *PBifaceT in assignment:
*PBifaceT is pointer to interface, not interface
prog.go:25: x.Pb.Step undefined (type *PBifaceT is pointer to interface, not interface)
我尝试将它们转换为in this playground:
func NewD() *PBifaceT {
// var err error
var res =new(ImplPBifaceT)
return (*PBifaceT)(res)
}
func main() {
x := TestDialogUiT{}
x.Pb = NewD()
parentId := x.Pb.Step()
fmt.Sprintf("%v", parentId)
}
问题:
prog.go:23: cannot convert res (type *ImplPBifaceT) to type *PBifaceT
prog.go:30: x.Pb.Step undefined (type *PBifaceT is pointer to interface, not interface)
答案 0 :(得分:2)
您确定需要将Pb
字段作为*PBifaceT
。
如果你把它保存为
type TestDialogUiT struct {
Pb *PBifaceT
}
你做了
x := TestDialogUiT{}
PbPb := ImplPBifaceT{}
x.Pb = PBifaceT(PbPb)
parentId := x.Pb.Step()
fmt.Printf("%v", parentId)
它运作正常..
看看这个playground,看看它是否有帮助。
我建议你也阅读this SO answer,它解释了你不应该如何使用接口指针。
背景:在Go中,你传递一个指向某事物的指针,原因有两个:
1)你想要的是因为你的结构非常大并且你想避免复制
2)你需要因为calee想要修改原文(这对于带有指针接收器的方法来说是典型的)。现在接口值非常小(只有两个字),所以原因1将指针传递给接口值不适用。
原因2在大多数情况下不适用,因为将指针传递给接口值将允许您更改接口值本身,但通常您希望修改存储在接口值中的值。存储在接口值中的这个值通常是一个指针值,它允许通过调用包装指向此结构的指针的接口值来更改结构的值。这听起来很复杂但不是:新手Go程序员只是不使用指针接口(因为这不会有任何好处)和经验丰富的Go程序员不使用指针接口(因为它不会做太多好的)除非他需要修改界面值,通常是在反射过程中。
答案 1 :(得分:1)
除非您确定是您想要的,否则请不要使用指向接口的指针,请参阅Pb *PBifaceT
内的TestDialogUiT
。如果您将其更改为Pb PBifaceT
,那么您的游乐场链接就可以正常工作。
接口已经是指针。
答案 2 :(得分:1)
你可以通过链接使用Pb,在分配时你只是缺少指针引用。
package main
import (
"fmt"
)
type PBifaceT interface {
Step() int
}
type TestDialogUiT struct {
Pb PBifaceT
}
type ImplPBifaceT struct {
}
func (m *ImplPBifaceT) Step() int {
return 0
}
func main() {
x := TestDialogUiT{}
PbPb := &ImplPBifaceT{}
x.Pb = PbPb
parentId := x.Pb.Step()
fmt.Printf("%v", parentId)
}
请参阅此游乐场链接:https://play.golang.org/p/N7quQFpYU0 变化分别在第12,17,23和12行。 27。