英文:
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())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论