英文:
Define method of struct inside function
问题
我有这段代码:
func baz() {
type mockDatabase struct{}
//
// 更多代码
//
}
我想定义一个mockDatabase
的方法,所以完整的代码应该是这样的:
func baz() {
type mockDatabase struct{}
func (m *mockDatabase) Foo() {
// 在这里实现函数
}
//
// 更多代码
//
}
我之所以这样做是因为我正在将一个依赖项注入到一个函数中,并且我想创建一个“模拟对象”来注入到该函数中(该函数以接口作为参数,模拟对象将实现该接口)。
我可以在外部创建结构体,但是在减少命名空间混乱方面,将结构体局部声明似乎更合理,特别是这些模拟对象只会被使用一次。我在这里有什么遗漏吗?将其定义在测试函数外部以避免代码过长是更好的做法吗?在这种情况下我应该怎么做?
英文:
I have this code
func baz() {
type mockDatabase struct{}
//
// More code
//
}
I want to define a method of mockDatabase
, so the full code would look like this:
func baz() {
type mockDatabase struct{}
func (m *mockDatabase) Foo() {
// Implement function here
}
//
// More code
//
}
The reason I want to do this is I'm injecting a dependency into a function, and I want to create a "mock object" to inject into the function (the function takes an interface as an argument and the mock object will implement the interface).
I could create the struct outside, but it seems more logical to declare the struct locally to decrease namespace clutter, especially when these mock objects will only be used once. Am I missing something here? Is it better practice to define it outside the test function so it's not long? What should I do here?
答案1
得分: 6
Go语言中的惯用方式是使用package进行命名空间管理。
package mock
type MockDatabase struct {}
func (m *MockDatabase) Foo() {}
在主要的代码中,你可以从包中调用:
package main
import (
"path/to/mock"
)
var m = mock.New(mock.MockDatabase)
func baz() {
m.Foo()
}
英文:
The idiomatic Go would be to use package for namespacing.
package mock
type MockDatabase struct {}
func (m *mockDatabase) Foo() {}
In the main code, you can call from the package
package main
import (
"path/to/mock"
)
var m = New(mock.MockDatabase)
func baz() {
m.Foo()
}
答案2
得分: 6
直接来说,不行。老实说,我认为pie-o-pah已经回答了你的问题。但是,如果你出于某种原因仍然想按照你的方式来做,你可以通过一些样板包装和巧妙地使用闭包来实现:
type I interface {
Foo()
}
type ExtendableI struct {
foo func()
}
func (i ExtendableI) Foo() {
i.foo()
}
func main() {
type MyI int
myI := MyI(42)
foo := func() {
fmt.Println(myI) // 闭包中引用myI,使其像一个方法一样工作。
}
ei := ExtendableI{foo: foo}
useI(ei) // useI 需要一个 I。
}
Playground: http://play.golang.org/p/G2HKhjb5fk。
英文:
Directly - no. And honestly, I think that pie-o-pah answered your question. But. If you still want to do it your way for some reason, you can do it with a little bit of boilerplate wrapping and clever use of closures:
type I interface {
Foo()
}
type ExtendableI struct {
foo func()
}
func (i ExtendableI) Foo() {
i.foo()
}
func main() {
type MyI int
myI := MyI(42)
foo := func() {
fmt.Println(myI) // Close over myI making it work like a method.
}
ei := ExtendableI{foo: foo}
useI(ei) // useI needs an I.
}
Playground: http://play.golang.org/p/G2HKhjb5fk.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论