How to initialize map without code duplication? - go

I have a struct type named as game as follows:
type game struct {
commands map[string]*command
// ...
}
And I want to initialize a map in a struct of this type in the init function. I do it like this
func (game *game) init() {
game.commands = make(map[string]*command)
// ...
}
As I think, there is some code duplication. It would be neat if I could declare the type (map[string]*command) only once. Is there a way to do that? I tried to use reflect but it doesn't seem to work because make builtin takes a type and not a value.

If you are worried that repeating map[string]*command two times is duplication, you can define a new type from it.
type commandsMap map[string]*command
type game struct {
commands commandsMap
// ...
}
func (game *game) init() {
game.commands = make(commandsMap)
// ...
}

There is not a code duplication here. Code duplication is when you have multiple points in your code that does the same thing.
That being said, you can leave your code like it is or you can use a Constructor, which has the benefit of restricting this initialization where you type is and is also a cleaner approach imho.
type game struct {
commands map[string]*command
}
func game() *game {
return &game{commands: make(map[string]*command)}
}
That way, when you need a game object, you can just do
gameObject := game()
and then use the map methods as you normally would (or you can also make a utility method just for that)

Related

How can I (or should I) use Go interfaces for picking one of two packages? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
OK, I'm not quite getting it....
I have 2 modules I crafted with identical functions (in different files of course):
package mod1
func MyFunc() string {
return "mod1.Myfunc"
}
func Func2() string {
return "mod1.Func2"
}
package mod2
func MyFunc() string {
return "mod2.MyFunc"
}
func Func2() string {
return "mod2.Func2"
}
I have an interface defined correctly, (I think) in a third package:
package types
type MyType interface {
MyFunc() string
Func2() string
}
I have code which can pick whether I want to use mod1 or mod2, but I'm not quite understanding what I should have this code return:
func mypicker() ????{
}
Then in main, I want to somehow call either mod1.MyFunc() or mod2.MyFunc() based on
mypicker, without knowing which it is.... something like this:
func main() {
p := mypicker()
fmt.Print(p.MyFunc())
// and later
fmt.Print(p.Func2())
}
I read that interfaces are like void *, but clearly I'm not getting the complete picture.
Pointers to docs, code, anything useful would be great.
Interfaces should be used with types, not just plain functions. You can start by reading the Tour of Go sequence on interfaces. Here's an example close to your question's original code:
Given the interface:
type MyType interface {
MyFunc() string
Func2() string
}
You'd have a type:
type MyType1 struct{}
func (mt MyType1) MyFunc() string {
return "MyType1.MyFunc"
}
func (mt MyType1) Func2() string {
return "MyType1.Func2"
}
And similarly:
type MyType2 struct{}
func (mt MyType2) MyFunc() string {
return "MyType2.MyFunc"
}
func (mt MyType2) Func2() string {
return "MyType2.Func2"
}
And now, if you have some function that takes your MyType interface:
func Foo(m MyType) {
fmt.Println(m.Func2())
fmt.Println(m.MyFunc())
}
You could call it with either of your types that implements that interface:
m1 := MyType1{}
Foo(m1)
m2 := MyType2{}
Foo(m2)
Here's a Go Playground link where you can try this in action.
As for "picking a type", perhaps you mean something like this:
var mi MyType
if (... some condition ...) {
mi = m1
} else {
mi = m2
}
// Now you can do with mi whatever its interfaces permits,
// like calling mi.Func2(), etc.
Regarding the "picking one of two packages" part of the question:
Interfaces are implemented by types; they're orthogonal to packages and modules. In other words, an interface and types that implement it can all be in the same package, or in different packages, or in different modules.
You have to be careful with terminology. Go modules and Go packages are very different, even though both can be contained by directories. Basically, a directory is a package if it has at least one Go file in it and no go.mod file. If a directory has a go.mod file in it then it's recognized as a module. Generally, a whole project can be a single module with the go.mod file at the root of the project and that's sufficient. Assuming this is your case, move forward thinking that every sub-directory is just a package within that single module.
An interface doesn't really have to do with modules or packages, it has to do with types. The reason being is that an interface defines behavior, meaning it defines what methods are required for a type to accurately implement that interface. In your case, you defined both functions declared in your interface BUT they are NOT METHODS because they are top-level functions only attached to the package. In order for a function to be a method, it must be "attached" to a type. Then, that type becomes a valid implementation of that interface.
This...
package mod1
func MyFunc() string {
return "mod1.Myfunc"
}
func Func2() string {
return "mod1.Func2"
}
Needs to become this...
package mod1
type MyTypeImpl struct {}
func (m MyTypeImpl) MyFunc() string {
return "mod1.Myfunc"
}
func (m MyTypeImpl) Func2() string {
return "mod1.Func2"
}
The naming could be improved greatly but the point is that the above function declaration syntax is how you "attach" a function to a type, making it a method, which allows that MyTypeImpl struct to now be a valid implementation of your MyType interface.
Now you can call the interface methods without regards to which underlying type is actually the implementation:
var iType MyType
iType = MyTypeImpl{}
iType.MyFunc()
Notice that in that last line, it does not matter that we used MyTypeImpl to implement the interface. Once the implementation is assigned to a variable with the interface type, we just work with the interface and forget the underlying implementation. When we call iType.MyFunc(), Go will call the proper method from the underlying implementation.
If we had 100 different structs that implemented the MyType interface as MyTypeImpl does, they could all work for the right side of that iType = MyTypeImpl{} line. That's the point of an interface, to define it once and then use it without regard to what underlying struct is actually implementing it.

Explain go interface definition in go wiki

I understand a bit a go and to certain extend understand interface as well(like how I do ducktyping in ruby)
But reading the interface definition https://github.com/golang/go/wiki/CodeReviewComments
I'm clueless what is trying to convey.
1st: I did not understood the comment.
Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values.
2nd: I do not understand this
Do not define interfaces on the implementor side of an API "for mocking"; instead, design the API so that it can be tested using the public API of the real implementation.
3rd: I do not understand the example
Do not define interfaces before they are used: without a realistic example of usage, it is too difficult to see whether an interface is even necessary, let alone what methods it ought to contain.
package consumer // consumer.go
type Thinger interface { Thing() bool }
func Foo(t Thinger) string { ..... }
package consumer // consumer_test.go
type fakeThinger struct{ … }
func (t fakeThinger) Thing() bool { … }
if Foo(fakeThinger{…}) == "x" { ... }
// DO NOT DO IT!!!
package producer
type Thinger interface { Thing() bool }
type defaultThinger struct{ … }
func (t defaultThinger) Thing() bool { … }
func NewThinger() Thinger { return defaultThinger{ … } }
package producer
type Thinger struct{ … }
func (t Thinger) Thing() bool { … }
func NewThinger() Thinger { return Thinger{ … } }
Can someone explain in plain and easier word the 3 things above.
Forget analogies with other languages for the moment. Think of an interface like a contract - a set of requirements for the function that uses it.
Say I define a function MakeNoise which needs to know the sound of the thing passed in, but otherwise doesn't care about it. Code below is all together, but imagine this in two separate packages - one for concrete types and one for MakeNoise.
The MakeNoise function could take a specific type, but this limits it somewhat, might make testing harder etc, so often you might want it instead to define what it needs the type to do - in this case it just needs something with a Sound() method to call, other than that it doesn't care.
Now on the Cat/Dog side, you might not care about MakeNoise, or even know about it yet, your animals should be defined separately and not care about any interfaces they conform with - those interfaces might not even have been written yet.
So the Wiki is just saying that whoever writes MakeNoise should care about what it requires and put that in an interface, but whoever writes Cat/Dog should not care, and the interface should sit with MakeNoise, not with Cat/Dog. This means later someone might come and write a Giraffe in another package, and it can still be used with MakeNoise.
The interface is a requirement, not a promise.
https://play.golang.org/p/4r1wiXokKMb
// Here are some types which share one function.
// They might have other functions too
package main
type Cat struct {}
func (d Cat) Sound() string {
return "miao"
}
type Dog struct {}
func (d Dog) Sound() string {
return "woof"
}
func main() {
cat := Cat{}
dog := Dog{}
MakeNoise(cat)
MakeNoise(dog)
}
// Sounder is the requirement for MakeNoise, so it lives with it.
// perhaps in a package together which knows nothing of cats and dogs.
type Sounder interface {
Sound() string
}
// MakeNoise prints the sound of the thing
// it only cares the thing makes a Sound
func MakeNoise(thing Sounder) {
println(thing.Sound())
}

Is there a way to create method hooks for structs in Go?

I want to create before save and after save method hooks for my Go structs how can I achieve this?
type Person struct {
FirstName string
LastName string
}
func (p *Person) Save() {
// call beforeSave()
// Save person data
// call afterSave()
}
func (p *Person) Update() {
// call beforeUpdate()
// Update person data
// call afterUpdate()
}
type Order struct {
Number bson.ObjectId
Items []Item
}
func (o *Order) Save() {
// call beforeSave()
// Save order data
// call afterSave()
}
func (o *Order) Update() {
// call beforeUpdate()
// Update order data
// call afterUpdate()
}
For any struct I create as a model I want it to have a beforeSave() and afterSave() hook called automatically and be able to further override if necessary.
Packages like gorm use callback hooks heavily. But if you are writing your own engine (for some specific logic) using interfaces can help greatly (sample).
https://medium.com/#matryer/the-http-handler-wrapper-technique-in-golang-updated-bc7fbcffa702
I would only add to that article above, which I think well answers your question, that you can go further using pipelines (methods that return the associated variable they are bound to). It's particularly interesting as in the above article, as relates to being able to interpose anything between two processes, and you can use this to create tees and journalling/logging systems, and it can go a long way towards compensating for the kinda primitive error handling in Go.
I designed a number of related byte slice processing libraries that were able to be easily chained without needing to break a a line, although obviously more than about 3-4 in a line can get confusing and you can find yourself wanting to pass things in a DAG style pattern, at which point I think channels would make sense.

Composition combining data and functions with interfaces and structs

I'm wondering if this is something that's done in Go or if I'm thinking about it all wrong: composing type x interface and type x struct so my interface methods have access to specific data too:
The C programmer in my wants to do this:
type PluginHandler interface {
onLoad()
pm *PluginManager
}
func (ph PluginHandler) onLoad() {
pm.DoSomething()
}
There I have an interface defined with a function, but also some data I want to pass to those functions but this is a syntax error.
So is this something that's doable in Go through some other method or am I just thinking about the problem wrong?
You have defined onLoad incorrectly. You cannot define a function directly on interface type.
Once you have an interface, you need another type to implement methods specified in the interface. For example, if another type implements onLoad method, they automatically (implicitly) implement the interface PluginHandler.
The other thing you need to do is change the interface function type to accept the required data:
type PluginHandler interface {
onLoad(*PluginManager)
}
struct SomeType {
// ...
}
func (s SomeType) onLoad(pm *PluginManager) { // SomeType now implements
pm.DoSomething() // PluginHandler interface.
}
This way, you get to inject whichever PluginManager required by PluginHandler.
Also, you can use SomeType as a PluginHandler type whereever required.
func someFuntion(ph PluginHandler) {
// ...
ph.onLoad(pm)
// ...
}
Can be called with an input argument of type SomeType:
s := SomeType{}
someFunction(s)
TL;DR; There is no direct translation to Go.
Long answer:
Go interfaces are only methods.
Go structs are only data (with the possibility of receiver methods).
You can reference, and even embed interfaces within structs:
type Frobnicator interface {
Frobnicate() error
}
type Widget struct {
Frobnicator
WidgetName string
}
But that's not really what you're talking about.
The best answer to your dilema is, I believe: Take a step back. You're focusing on the trees, and you need to look at the forest. Go takes a different approach than C, or classical OO languages like C++ and Java.
Look at the general problem to be solved, and find solutions to that in Go. This can be a painful process (I can say from experience), but it's really the only way to learn the new way of thinking.
Just for the record, you can add extra methods to an existing type, by introducing another (indirection) type as:
type HandlerManager PluginManager
func (x *HandlerManager) onLoad() {
((*PluginManager)(x)).DoSomething()
}
And if you need to go with a more generic solution, a combination of Adapter & Strategy patterns could do:
type PluginHandlerAdapter struct{ _onLoad func() }
func (x *PluginHandlerAdapter) onLoad() {
x._onLoad()
}
Used like (public/private access ignored):
type PluginManager struct {
PluginHandlerAdapter
}
func NewPluginManager() *PluginManager {
res := new(PluginManager)
res._onLoad = res.DoSomething
return res
}

How can I invoke a variable method on a struct

I want to invoke a variable method on a struct like this example
type controller struct{}
func (c *controller) Index() {
fmt.Println("index controller")
}
func invokeIt(action string) {
(&controller{}).action // don't work duh
(&controller{})["action"] // this is Go not js
// how can I invoke it?
}
thx for the replies.
DHH, are you porting Rails to Go :) ?
Jokes aside, this is exactly what reflect is for. For example:
type Foo struct{}
func (Foo) FooM() { fmt.Println("Foom") }
func main() {
foo := Foo{}
reflect.ValueOf(foo).MethodByName("FooM").Call(nil)
}
Playground: http://play.golang.org/p/5ZGwlHLEmj
EDIT: A more idiomatic way to do it would be to use interfaces, (as someone else had proposed, but then have deleted their answer). So if you want to, say, define something that can do CRUD, in Go you'd usually go with
type Resources interface {
Index()
New()
Show(id int)
// ...
}
And maybe an Invoke method in order to invoke non-standard methods on this thing using reflect like above. reflect is very powerful and also a good way to shoot yourself in the foot, so it's never a good idea to overuse it.

Resources