I am learning golang, and am getting stuck on an embarassingly simple concept. Maybe it's my OO habits clouding my comprehension, but I can't seem to get this simple example to work:
package main
import (
"fmt"
)
type datafield struct {
name string
value string
}
func (d datafield) NewField(name, value string) *datafield {
retval := new(datafield)
retval.name = name
retval.value = value
return retval
}
func main() {
field := datafield.NewField("name", "value")
if field == nil {
fmt.Println("Error: Did not create a datafield")
} else {
fmt.Println("Success!")
}
}
The error is:
prog.go:20:29: not enough arguments in call to method expression datafield.NewField
have (string, string)
want (datafield, string, string)
What is the proper way to get NewField(string,string) to create a datafield?
Go isn't exactly object oriented language and promotes simplicity, that's why the previous answers are focused on fixing your code. Nevertheless, if you really need to implement this design pattern in Go, read further.
The factory method pattern is a creational pattern that uses factory
methods to deal with the problem of creating objects without having to
specify the exact class of the object that will be created. This is
done by creating objects by calling a factory method. (wikipedia)
Here is another definition and a really good example in Go by Svetlin
Ralchev:
The Factory Method pattern is used to define a runtime interface for
creating an object. It’s called a factory because it creates various
types of objects without necessarily knowing what kind of object it
creates or how to create it. (Desing Patterns in Golang: Factory
Method)
I've extended your example a bit to demonstrate the benefits of using Factory Methods, as there is no need to use factories at all if you're dealing with one struct (an object in OO world).
https://goplay.space/#SOXPmM86GgF
package main
import (
"fmt"
)
type dataField interface {
Print()
}
type dataField1 struct {
name string
value string
}
func (df *dataField1) Print() {
fmt.Println("dataField1 ->", df.name, ":", df.value)
}
type dataField2 struct {
name string
value string
}
func (df *dataField2) Print() {
fmt.Println("dataField2 ->", df.name, ":", df.value)
}
type dataFieldFactory interface {
Create(name, value string) dataField
}
type dataField1Factory struct{}
func (factory *dataField1Factory) Create(name, value string) dataField {
return &dataField1{
name: name,
value: value,
}
}
type dataField2Factory struct{}
func (factory *dataField2Factory) Create(name, value string) dataField {
return &dataField2{
name: name,
value: value,
}
}
type Document struct {
dataFieldFactories []dataFieldFactory
allValues [][]string
}
func (doc *Document) Print() {
for i, factory := range doc.dataFieldFactories {
field := factory.Create(doc.allValues[i][0], doc.allValues[i][1])
field.Print()
}
}
func main() {
doc := &Document{
dataFieldFactories: []dataFieldFactory{
&dataField1Factory{},
&dataField2Factory{},
},
allValues: [][]string{{"name1", "value1"}, {"name2", "value2"}},
}
doc.Print()
}
The program simply prints this
dataField1 -> name1 : value1
dataField2 -> name2 : value2
However, if you look into main func you don't find any mentions or initializations of concrete types dataField1 and dataField2.
All the complexity is hidden behind dataFieldFactories.
Both dataField1Factory and dataField2Factory implement Create interface and return dataField interface, that both the concrete types
also implement. So, you can call Print() for each of the concrete types.
Document.Print() uses both the Create and Print interfaces for printing
out all the fields without any knowledge about how the fields are actually created or printed. We're achieving this by providing a list of Factory Methods (dataField1Factory{} and dataField2Factory{}) and corresponding string values to the Document struct (object).
Excuse me for a bit artificial example, but I hope, you'll get the basic idea.
As you can see Go allows you to implement design patterns you're familiar with, perhaps, not in exact same way as you get used to in pure OO languages.
You must not set a method on type "datafield" in your case, but do this instead :
func NewField(name, value string) *datafield {
retval := new(datafield)
retval.name = name
retval.value = value
return retval
}
By adding (d datafield) onto the function signature you are making the datafield a receiver argument (https://tour.golang.org/methods/1) so the NewDatafield is now a method on datafield. This means to call it you need to already have a datafield which didn't make much sense so you could just remove the (d datafield) and it will work or even better just construct the stuct directly (https://gobyexample.com/structs):
field := datafield{"name", "value"}
You only really need constructor functions when there is extra work to be done, not just setting fields.
Related
Following code throws a compilation error
cannot use ExampleProps (variable of type Props[Example]) as Props[Generic] value in return statement
// Abstract
type Generic interface {
ID() string
}
type Props[G Generic] struct{}
// Example
type Example struct {
id string
}
func (example Example) ID() string {
return example.id
}
var ExampleProps = Props[Example]{}
// Problem
func Problem() Props[Generic] {
return ExampleProps
}
My question is: as Example implements Generic, why does Go not allow assigning Props[Example] to Props[Generic]?
Instantiating a generic type with different type arguments produces two new different named types.
Note that every time you supply a type argument, including in function arguments or return types, you are instantiating the generic type:
// Props is instantiated with type argument 'Generic'
func Problem() Props[Generic] {
return ExampleProps
}
Therefore Props[Example] is just not the same type as Props[Generic] and you can't use values of one type wherever the other one is expected. It does not matter if the types used as arguments themselves meet some condition for assignability, e.g. interfaces and implementors.
This is also true of generics instantiated with any. The type any is just another static type — alias of interface{}. It's not equal to T and it's not equal to "whatever type".
In simpler terms it’s as if you were using int where string is expected.
What you can do fix it and keep some flexibility is to instantiate Props with a type parameter — whether this makes sense or not depends on how you actually plan to use this function. Anyway, as demonstration:
// adding a field to make this a bit less contrived
type Props[G Generic] struct{ Value G }
// Props instantiated with T, adequately constrained
func Problem[T Generic](v T) Props[T] {
return Props[T]{ Value: v }
}
func main() {
a := Problem(Example{})
fmt.Println(a)
}
Playground: https://gotipplay.golang.org/p/wcDOtJ6z80u
There are some generated code I cannot change. They have the general structure like below:
// These structures & methods I cannot change
type NotMyStruct struct {
EmbeddedCaller
}
type EmbeddedCaller struct {
foobar string
}
func (_embeddedCaller *EmbeddedCaller) DoStuff() string {
return "ABC"
}
func NewNotMyStruct() *NotMyStruct {
return &NotMyStruct{
EmbeddedCaller{"blah"},
}
}
The general pattern of the generated code is 1) a parent struct + an embedded struct 2) a method on the embedded struct and 3) a New method that creates the struct.
I have a number of these generated "contracts" and they all have different types, ie NotMyStruct1 NotMyStruct2 etc etc. The embedded structs are all different types as well, ie EmbeddedCaller1, EmbeddedCaller2 etc.
However they all have the same method DoStuff with the same return value. What I would like to do is create a map of some id to the New functions then iterate over each of these and call the DoStuff method. However my code does not compile. it would look something like this if it compiled:
type MyDoStuffInterface interface {
DoStuff() string
}
var instantiations map[string]func()*MyDoStuffInterface{
"1": NewNotMyStruct, //<-- does not compile here because *MyDoStuffInterface doesn't match *NotMyStruct
...
}
for id, instantiationFunc := range instantiations {
instance := instantiationFunc()
instance.DoStuff()
}
Is it possible to do what I'm trying to do? If so how? If not, what is the easiest way to keep things dry?
First, you need to replace *MyDoStuffInterface with MyDoStuffInterface. Pointers to interfaces do have their uses, but nearly all of the time they aren't needed (or correct).
Second, the type of your function (func()*NotMyStruct) doesn't match func()MyDoStuffInterface. (People more experienced in types than me might say that function types in go aren't covariant or something like that).
The best way to solve this second problem is to use a wrapper function that has the correct type. (An alternative is to avoid the type system and use interface{} for your function type and use run-time reflection to call your function).
Here's a full compiling example (playground link). (I had to change your instantiations variable a little because the syntax for initializing a map wasn't correct.)
package main
type NotMyStruct struct {
EmbeddedCaller
}
type EmbeddedCaller struct {
foobar string
}
func (_embeddedCaller *EmbeddedCaller) DoStuff() string {
return "ABC"
}
func NewNotMyStruct() *NotMyStruct {
return &NotMyStruct{
EmbeddedCaller{"blah"},
}
}
type MyDoStuffInterface interface {
DoStuff() string
}
func main() {
var instantiations = map[string](func() MyDoStuffInterface){
"1": func() MyDoStuffInterface { return NewNotMyStruct() },
}
for _, instantiationFunc := range instantiations {
instance := instantiationFunc()
instance.DoStuff()
}
}
Use the following map:
var instantiations = map[string]func()MyDoStuffInterface{
"1": func() MyDoStuffInterface {
return NewNotMyStruct()
},
}
Some notes:
The anonymous "adaptor" function is required because NewNotMyStruct() returns a *NotMyStruct, not a MyDoStuffInterface.
Do not use a pointer to an interface. They are not needed.
Run it on the Go Playground.
I've inherited some code that looks like this:
type FooWrapper struct {
Stuffer interface{ GetStuff() *grpc.Stuff }
Thinger interface{ GetThing() *grpc.Thing }
Widgeter interface{ GetWidget() *grpc.Widget }
// many more like these
}
func NewFooWrapper(v proto.Message) FooWrapper {
var w FooWrapper
w.Stuffer, _ = v.(interface{ GetStuff() *grpc.Stuff })
w.Thinger, _ = v.(interface{ GetThing() *grpc.Thing })
w.Widgeter, _ = v.(interface{ GetWidget() *grpc.Widget })
// many more like these
return w
}
func (w FooWrapper) GetStuff() *grpc.Stuff {
if w.Stuffer == nil {
return nil
}
return w.Stuffer.GetStuff()
}
// many more methods like this one
We can see that this code does the following:
It declares a FooWrapper struct with a bunch of anonymous interface fields, one for each method that can possibly exist in any implementation of proto.Message.
The NewFooWrapper constructor is converting v to each one of those anonymous interface types, discarding the error. Thus, if the type boxed in v does not have the GetXXX method, the related field in w will simply be nil
FooWrapper getters check if the corresponding field is nil and if it's not, it invokes the method on the boxed value.
To me this seems a quite verbose way of implementing a type switch, though I'm not sure this is idiomatic Go code.
However I guess it could be useful in cases where v had to be passed to multiple unrelated methods, causing the type switch to be copy-pasted everywhere (it's not the case of the code I got here).
Is this code equivalent to a type switch, in practice?
What are the advantages in using this pattern instead of a type switch?
In a word, "no", it's not idiomatic. But of course that doesn't mean it's "wrong".
Although given that the anonymous interface types are repeated, it seems pretty silly to do that, rather than a named type.
If I had inherited that code, I would immediately change it.
And with that exact code sample in mind, I would also re-define my struct to use embedded interfaces:
type Stuffer interface { GetStuff() *grpc.Stuff }
type Thinger interface { GetThing() *grpc.Thing }
type Widgeter interface { GetWidget() *grpc.Widget }
type FooWrapper struct {
Stuffer
Thinger
Widgeter
// many more like these
}
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.
I have a struct which represents an object in a database, something like:
type Object struct {
Id string
Field1 string
Field2 int
}
And I'd like to have a function that updates the specific field in the database whenever the field is modified, something along these lines:
func (self *Object) SetField1(value string) {
self.Field1 = value
database.Update(self.Id, "Field1", self.Field1) // pseudocode
}
Is there a way to replace the "Field1" hard-coded string such that my code is resistant to future changes in the struct field ordering and naming?
I've poked around the reflect package, and it would be nice to be able to get the StructField that represents the field I'm working with, but it seems to require either the name of the field via hard-coded string, or the field's index in the struct (which is subject to change).
not in the context that you're talking about. It's not passed in as a parameter, so you need some other way of specifying which of the struct's fields to be sent. The mental gap here is you're trying to treat that set function like it's a property when it's not; the key difference between a property, as seen in other languages, is that a property is bound to a specific field, whereas your SetField1 method is bound to the whole struct. That method might as well set two fields.
Generally if you're doing field-wise reflective stuff, and you want to do fancy dynamic stuff with fields, you want to use struct tags. e.g., like this:
type Object struct {
Id string `db:"id"`
Field1 string `db:"field1"`
Field2 int `db:"field2"`
}
you can access those tags like-a-this:
package main
import (
"reflect"
"fmt"
)
func main() {
var x struct {
MyField int `core:"required"`
}
t := reflect.TypeOf(x)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fmt.Println(field.Name, ":", field.Tag.Get("core"))
}
}
that's not really a full solution, but... the question in the way it's asked is impossible to do.
You could validate your string by adding a method something like this:
func (self *Object) verify(field string) string {
if _, ok := reflect.TypeOf(*self).FieldByName(field); ok {
return field
}
panic("Invalid field name")
}
And then use it when passing the string to the database update
func (self *Object) SetField1(value string) {
self.Field1 = value
database.Update(self.Id, self.verify("Field1"), self.Field1) // pseudocode
}
But I would think that if you're willing to use reflection, that you'd be better off just making a generic setField method that accepts the field as a string, and the value as a interface{}, checks the field and value, sets the value and updates the database.
This way everything is done using the string, so it'll either work or panic, and you don't need to remember to use the .verify() method.
Somthing like:
func (self *Object) SetField(field string, value interface{}) {
// verify field and value using reflection
// set the value using reflection
database.Update(self.Id, field, self.Field1)
}
Though I don't think this'll work on unexported fields.