How come I can say that the result of CreateLion(), a pointer to a struct that implements the Cat interface, is an instance of the Cat interface, and yet I cannot say that CreateLion() is of type "function that returns the Cat interface."
What is the standard Golang approach to achieving this type of behavior?
package main
import "fmt"
func main() {
var lion Cat := CreateLion()
lion.Meow()
// this line breaks. Why?
var cf CatFactory = CreateLion
}
type Cat interface {
Meow()
}
type Lion struct {}
func (l Lion) Meow() {
fmt.Println("Roar")
}
// define a functor that returns a Cat interface
type CatFactory func() Cat
// define a function that returns a pointer to a Lion struct
func CreateLion() *Lion {
return &Lion{}
}
Try this:
package main
import "fmt"
type Cat interface {
Meow()
}
type Lion struct{}
func (l Lion) Meow() {
fmt.Println("Roar")
}
type CatFactory func() Cat
func CreateLion() Cat {
return Lion{}
}
func main() {
lion := CreateLion()
lion.Meow()
var cf CatFactory = CreateLion
fLion := cf()
fLion.Meow()
}
In most cases, you can assign any type to base type interface{}. But situation changes if type of function parameter is a map[T]interface{}, []interface{} or func() interface{}.
In this case the type must be the same.
I think you should read this blog http://blog.golang.org/laws-of-reflection,it is precise about the relation between variables,types and interfaces.
In your example *Lion is different with Cat.
You can correct function CreateLion returns from *Lion to Cat.
The problem here is that statically typed go differentiates the "this is a function that returns a cat" from "this is a function that returns a lion that is a cat" And therefore will not accept one as the other.
The way to fix this is to give your factory var exactly what it expects:
var cf CatFactory = func() Cat{
return CreateLion()
}
catlion := cf()
catlion.Meow()
Works fine with a few changes. Check it out here: https://play.golang.org/p/ECSpoOIuzEx
package main
import "fmt"
func main() {
lion := CreateLion() // Go idomatic style recommends
// allowing the compiler to divine the type
lion.Meow()
CatFactory := CreateLion
_ = CatFactory // Go doesn't like unused variables and fails the build
obj := CatFactory() // exercising our factory method
obj.Meow()
}
type Cat interface {
Meow()
}
type Lion struct {}
func (l Lion) Meow() {
fmt.Println("Roar")
}
// define a functor that returns a Cat interface
type CatFactory func() Cat
// define a function that returns a pointer to a Lion struct
func CreateLion() *Lion {
return &Lion{}
}
Also, though Go doesn't have Java style interfaces, it does have interfaces and you can achieve polymorphism, but the types are known at compile time.
You can model an "Is A" relationship, if both types implement the same interface. However it doesn't enforce the interface until you pass the object into a function that accepts that interface type. So if you imagine implementing the Strategy pattern, when you're passing in the strategy object matching interface "Cat", that function will accept a "Lion" object, or any other class that implements a Meow function with the correct signature.
Also, factory methods are definitely necessary and useful in Go. In fact, instead of constructors, in Go, you use factory functions to construct your objects.
Related
I am really new to golang and I am trying to see how encapsulation really works in go.
I have the following structure
-- package a
-a_core.go
-a.go
-models.go
-- main.go
In models.go I have structs for request and responses for an api call,
a.go has an empty struct, which is private and a public interface, which I want to expose with various methods
a_core.go just has some business logic which would be called in my interface implementation
Then, I have a main.go where I just call the public interface.
code in a.go
package a
type myFunction struct{}
type MyFunc interface {
Create(myData *MyData) (*MyData, error)
Fetch(test string)
Delete(test string)
}
//Concrete implementations that can be accessed publicly
func (a *myFunction) Create(data *MyData) (*MyData, error) {
return nil, nil
}
func (a *myFunction) Fetch(test string) {
}
func (a *myFunction) Delete(test string) {
}
In main.go, I call the interface my first create the MyData pointer with values
data := &a.MyData{
/////
}
result, err := a.MyFunc.Create(data)
I get the following error when I do this,
too few arguments in call to a.MyFunc.Create
cannot use data (variable of type *a.MyData) as a.MyFunc value in argument to a.MyFunc.Create: missing method CreatecompilerInvalidIfaceAssign
Please what am I doing wrong?
Here is an example
Note that names in uppercase are public, in lowercase private (see https://tour.golang.org/basics/3 )
./go-example/main.go
package main
import "go-example/animal"
func main() {
var a animal.Animal
a = animal.Lion{Age: 10}
a.Breathe()
a.Walk()
}
./go-example/animal/animal.go
package animal
import "fmt"
type Animal interface {
Breathe()
Walk()
}
type Lion struct {
Age int
}
func (l Lion) Breathe() {
fmt.Println("Lion breathes")
}
func (l Lion) Walk() {
fmt.Println("Lion walk")
}
We all know dependency injection makes packages decoupled.
But I'm a little confused about best practices of dependency injection in go.
Lets assume package User needs to access Config package.
We can pass a Config object to User methods. In this way I can change the Config package functionality as long as the new code resolves the interfaces.
Another approach is call Config package methods directly , In these scenario I can change Config code too as long as the methods names remains the same. Like so
Update :
What is different between these two approaches :
package User
func foo(config ConfigObject) {
config.Foo()
}
And this one :
package User
import Config
func foo() {
config.Foo()
}
Calling config.Foo on the config argument to a method means that you receive an instance of some structure (possibly implementing interface Config) and call the method Foo on that instance/interface. Think of this as of calling a method of an object in OO terms:
package user
func foo(cfg config.Config) {
cfg.Foo()
}
Calling config.Foo having imported the config package means you are calling the function Foo of package config, not of any object/struct/interface. Think of this as pure procedural programming without any objects:
package user
import config
func foo() {
config.Foo()
}
The latter has nothing to do with dependency injection, the former may constitute a part of it if Config is an interface.
Dependency injection, on the other hand, follows generally the same rules in Go as in other languages:
accept interfaces, supply implementations
Because in Go structs satisfy interfaces implicitly rather than explicitly (as it is the case in Java)
the code accepting the value only needs to know about the interface and import it;
the code implementing it does not even need to know about the interface (it can just happen that it satisfies it);
the code that supplies the impl into a method accepting an
interface, obviously, needs to know both.
For your example this means:
package config
type Config interface {
Foo() string
}
package foo
type Foo struct{}
func (f *Foo) Foo() string {
return "foo"
}
package boo
type Boo struct{}
func (b *Boo) Foo() string {
return "boo"
}
package main
func foo(cfg config.Config) string{
return cfg.Foo()
}
func main() {
// here you inject an instance of Foo into foo(Config)
log.Print(foo(&foo.Foo{}))
// here you inject an instance of Boo into foo(Config)
log.Print(foo(&boo.Boo{})
}
Prints
2018/03/03 13:32:12 foo
2018/03/03 13:32:12 boo
Since, in my opinion, the example code given by previous poster(s) could be a bit less confusing for beginners, just by renaming things, i quickly try to do this here:
package contracts
type IConfig interface {
GetSomeString() string
}
package pkg1
type Foo struct{}
func (f *Foo) GetSomeString() string {
return "hello“
}
package pkg2
type Boo struct{}
func (b *Boo) GetSomeString() string {
return "world"
}
package main
func run(config contracts.IConfig) string {
s := config.GetSomeString()
return s
}
func main() {
foo := &pkg1.Foo{}
result1 := run(foo)
log.Print(result1)
boo := &pkg2.Boo{}
result2 := run(boo)
log.Print(result2)
// Prints: helloworld
// You learned:
// Since the run() func use a IConfig interface as
// parameter, the run() func can handle both struct
// types (Foo and Boo) as input, because both struct
// types (Foo and Boo) implement the IConfig interface.
}
Rule is, methods can be defined only on named type and pointer to named type.
For the below code,
package main
type Cat struct {
}
func (c Cat) foo() {
// do stuff_
}
func (c *Cat) foo() {
// do stuff_
}
func main() {
}
compiler gives error:
main.go:10: method redeclared: Cat.foo
method(Cat) func()
method(*Cat) func()
Above code defines,
method foo() for named type(Cat) and
method foo() for pointer to named type(*Cat).
Question:
For GO compiler, Why methods defined for different type is considered
same?
In Go, receivers are a kind of syntactic sugar. The actual, runtime signature of function (c Cat) foo() is foo(c Cat). The receiver is moved to a first parameer.
Go does not support name overloading. There can be only one function of with name foo in a package.
Having said the statements above, you see that there would be two functions named foo with different signatures. This language does not support it.
You cannot do that in Go. The rule of thumb is to write a method for a pointer receiver and Go will use it whenever you have a pointer or value.
If you still need two variants, you need name the methods differently.
For example, you can model some feline behavior like this:
package main
import (
"fmt"
)
type Growler interface{
Growl() bool
}
type Cat struct{
Name string
Age int
}
// *Cat is good for both objects and "object references" (pointers to objects)
func (c *Cat) Speak() bool{
fmt.Println("Meow!")
return true
}
func (c *Cat) Growl() bool{
fmt.Println("Grrr!")
return true
}
func main() {
var felix Cat // is not a pointer
felix.Speak() // works :-)
felix.Growl() // works :-)
var ginger *Cat = new(Cat)
ginger.Speak() // works :-)
ginger.Growl() // works :-)
}
I am trying to make something real simple on Go: to have an interface with getter and setter methods. And it seems setter methods are not allowed.
Given this code:
package main
import "fmt"
type MyInterfacer interface {
Get() int
Set(i int)
}
type MyStruct struct {
data int
}
func (this MyStruct) Get() int {
return this.data
}
func (this MyStruct) Set(i int) {
this.data = i
}
func main() {
s := MyStruct{123}
fmt.Println(s.Get())
s.Set(456)
fmt.Println(s.Get())
var mi MyInterfacer = s
mi.Set(789)
fmt.Println(mi.Get())
}
Set method does not work, because in func (this MyStruct) Set(i int), this MyStruct is not a pointer, and the changes are lost as soon at the function exits. But making it this *MyStruct would not compile. Is there any workaround?
Here is a corrected version of your code (playground). This isn't exactly Polymorphism, but the use of an interface is good Go style.
package main
import "fmt"
type MyInterfacer interface {
Get() int
Set(i int)
}
type MyStruct struct {
data int
}
func (this *MyStruct) Get() int {
return this.data
}
func (this *MyStruct) Set(i int) {
this.data = i
}
func main() {
s := &MyStruct{123}
fmt.Println(s.Get())
s.Set(456)
fmt.Println(s.Get())
var mi MyInterfacer = s
mi.Set(789)
fmt.Println(mi.Get())
}
I once found this example of how to do polymorphism in Go:
http://play.golang.org/p/6Ip9scm4c3
package main
import "fmt"
type Talker interface {
Talk(words string)
}
type Cat struct {
name string
}
type Dog struct {
name string
}
func (c *Cat) Talk(words string) {
fmt.Printf("Cat " + c.name + " here: " + words + "\n")
}
func (d *Dog) Talk(words string) {
fmt.Printf("Dog " + d.name + " here: " + words + "\n")
}
func main() {
var t1, t2 Talker
t1 = &Cat{"Kit"}
t2 = &Dog{"Doug"}
t1.Talk("meow")
t2.Talk("woof")
}
To answer the question the in the title to post:
Go does not use classes, but provides many of the same features:
* message passing with methods
* automatic message delegation via embedding
* polymorphism via interfaces
* namespacing via exports
From: http://nathany.com/good/
Solving the code you supplied, I will leave to some more learned Gopher
###AD HOC polymophism
Ad hoc polymorphism is a general way of polymorphism implementation for statically typed languages. Polymorphism in Go is ad hoc polymorphism which is very close to Bjarne's Stroustrup definition:
Polymorphism – providing a single interface to entities of different types.
Interfaces
Go interface is really powerful tool designed specially for polymorphism implementation. Interface is a type abstraction (sets of methods) which provides a way to specify the behavior of an object: if something can do this, then it can be used here. Back to Straustrup's polymorphism definition: it is possible to use objects of different types as a type of a common interface if they implement the interface.
Playground with an example.
Parametric polymorphism
Wiki:
A function or a data type can be written generically so that it can handle values identically without depending on their type.
This kind of polymorphism is more regular for dynamically typed languages like Python or Ruby but Go implements it too! Go uses type empty interface interface{} for this purpose.
Type interface{}
From Tour Of Go:
The interface type that specifies zero methods is known as the empty interface:
interface{}
An empty interface may hold values of any type. Every type implements at least zero methods.
Empty interfaces are used by code that handles values of unknown type. For example, fmt.Print takes any number of arguments of type interface{}.
And it is possible to get particular type of an object with type assertion.
And again Tour Of Go:
A type assertion provides access to an interface value's underlying concrete value.
t := i.(T)
This statement asserts that the interface value i holds the concrete type T and assigns the underlying T value to the variable t.
There we have parametric polymorphism with static duck typing.
The Golang "fmt" package has a dump method called Printf("%+v", anyStruct). I'm looking for any method to dump a struct and its methods too.
For example:
type Foo struct {
Prop string
}
func (f Foo)Bar() string {
return f.Prop
}
I want to check the existence of the Bar() method in an initialized instance of type Foo (not only properties).
Is there any good way to do this?
You can list the methods of a type using the reflect package. For example:
fooType := reflect.TypeOf(&Foo{})
for i := 0; i < fooType.NumMethod(); i++ {
method := fooType.Method(i)
fmt.Println(method.Name)
}
You can play around with this here: http://play.golang.org/p/wNuwVJM6vr
With that in mind, if you want to check whether a type implements a certain method set, you might find it easier to use interfaces and a type assertion. For instance:
func implementsBar(v interface{}) bool {
type Barer interface {
Bar() string
}
_, ok := v.(Barer)
return ok
}
...
fmt.Println("Foo implements the Bar method:", implementsBar(Foo{}))
Or if you just want what amounts to a compile time assertion that a particular type has the methods, you could simply include the following somewhere:
var _ Barer = Foo{}