【问题标题】:interfaces with getters and setters in go language与 go 语言中的 getter 和 setter 接口
【发布时间】:2017-07-26 02:08:06
【问题描述】:

我是 Go 语言的新手,在使用 getter 和 setter 从不同文件指定结构的接口时遇到问题。


来源

src/github.com/user/interfaces

package interfaces

type IFoo interface {
    Name() string
    SetName(name string)
}

src/github.com/user/foo

package foo

import "github.com/user/interfaces"

type Foo struct {
    name string
}

func (f *interfaces.IFoo) SetName(name string) {
    f.name = name
}

func (f IFoo) Name() string {
    return f.name
}

如果我将 struct Foo 的方法签名更改为以下,则 import "github.com/user/interfaces" 将变为未使用。

func (f *Foo) SetName(name string) {
    f.name = name
}

func (f Foo) Name() string {
    return f.name
}

测试

test/github.com/user/foo/foo_test.go

package foo

import (
    "testing"
    "github.com/user/foo"
    "fmt"
    "github.com/user/interfaces"
)

func TestFoo(t *testing.T) {
    foo := foo.Foo{}

    fmt.Println(interfaces.IFoo(foo))
}

问题:我怎样才能在上面的例子中为 Foo 结构体指定 IFoo 接口并让单元测试通过?

【问题讨论】:

    标签: go


    【解决方案1】:

    如何指定 Foo 结构的 IFoo 接口

    你没有。在 Go 中,接口实现是隐式的。见https://tour.golang.org/methods/10

    也就是说,如果 Foo 实现了 IFoo 接口的所有方法,它就实现了该接口。您无需“告诉”结构它是 IFoo。

    你要做的就是

    func (f *Foo) SetName(name string) {
        f.name = name
    }
    
    func (f Foo) Name() string {
        return f.name
    }
    

    然后在你的测试中你可以这样做:

    test/github.com/user/foo/foo_test.go
    
    package foo
    
    import (
        "testing"
        "fmt"
        "github.com/user/interfaces"
    )
    
    func TestFoo(t *testing.T) {
        var foo interfaces.IFoo = &Foo{}
        foo.SetName("bar")
        fmt.Println(foo.Name())
    }
    

    编辑:您的测试文件应该与它正在测试的文件位于同一个文件夹中,您不应该将它们全部放在test 文件夹中。话虽这么说,如果你想保持结构相同,你需要确保你的包名foo没有被你的变量名foo覆盖,然后在Foo{}前面加上foo:

    test/github.com/user/foo/foo_test.go
    
    package foo
    
    import (
        "testing"
        "fmt"
        "github.com/user/interfaces"
        "github.com/user/foo"
    )
    
    func TestFoo(t *testing.T) {
        var f interfaces.IFoo = &foo.Foo{}
        f.SetName("bar")
        fmt.Println(f.Name())
    }
    

    【讨论】:

    • 感谢您的清理,我很清楚隐式实现,但是,您的代码测试部分有错误。您可以从问题链接下载源代码以获得确切答案。这是说unresolved Type Foo 是你的TestFoo 函数的第一行
    • 可能是因为当我们已经在 foo 包中时它有 import "github.com/user/foo",我把它拿出来了,应该可以工作。
    • 实际上,等等...您的文件名是test/github.com/user/foo/foo_test.go - 您是否在名为test 的文件夹中拥有所有内容?如果是这样,您不应该,它 foo_test.go 应该与 foo.go 位于同一目录中
    • 还是test/github.com/user/foo/foo_test.go:10: undefined: Foo,我的#10,你的#11。是的,我的测试在不同的文件夹中,请下载 Dropbox 以查看结构。 dropbox.com/s/78sz2lxnly9dwyr/IFoo.zip?dl=0
    • 我在工作,文件共享网站都被屏蔽了,所以不能。正如我所说,测试不应该在不同的文件夹中,它们应该就在实际文件旁边。看看github.com/gorilla/mux,看看他们是如何构建它的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多