如何在以下代码中实现接口?

时间:2016-06-29 07:35:29

标签: pointers go interface

我有以下代码,我想使用接口:

当前代码:

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)

3 个答案:

答案 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,看看它是否有帮助。

我建议你看一下tutorialthis doc

我建议你也阅读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。