在Go语言中,使用getter和setter与接口进行交互。

huangapple go评论83阅读模式
英文:

interfaces with getters and setters in go language

问题

我是你的中文翻译助手,以下是翻译好的内容:

我对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
}

如果我将结构体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))
}

**问题:**在上面的示例中,我如何指定IFoo接口给Foo结构体,并使单元测试通过?

英文:

I'm new to go language and having problems specifying an interface to a struct from different files with a getter and setter.


Source

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
}

If I change method signature of struct Foo to the following then the import "github.com/user/interfaces" becomes unused.

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

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

Test

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))
}

Question: How can I specify the IFoo interface to the Foo struct and have the unit test pass in the above example?

答案1

得分: 5

如何将IFoo接口指定给Foo结构体?

在Go语言中,接口的实现是隐式的。如果Foo结构体实现了IFoo接口的所有方法,那么它就实现了该接口。你不需要“告诉”结构体它是一个IFoo接口。

你只需要这样做:

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

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

然后在你的测试代码中可以这样写:

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前缀:

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())
}
英文:

> How can I specify the IFoo interface to the Foo struct

You don't. In Go, interface implementation is implicit. See https://tour.golang.org/methods/10.

Which is to say, if Foo implements all of the methods of the IFoo interface, it implements the interface. You don't need to "tell" the struct that it is an IFoo.

All you have to do is

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

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

And then in your test you can do:

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())
}

Edit: Your test file should live in the same folder as the file it is testing, you should not have them all in a test folder. That being said, if you want to keep the structure the same, you would need to make sure that your package name foo is not overwritten by your variable name foo, and then prefix Foo{} with 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())
}

huangapple
  • 本文由 发表于 2017年3月10日 01:47:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/42702117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定